blob: 14868a5442d6c08d00cf1f1519696d9099981b34 [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;
phweiss923d2cc2016-12-14 21:37:48 +010039import android.app.admin.DevicePolicyManager;
Jason Monk62515be2014-05-21 16:06:19 -040040import android.app.IActivityManager;
Joe Onorato808182d2010-07-09 18:52:06 -040041import android.app.Notification;
42import android.app.PendingIntent;
Joe Onorato808182d2010-07-09 18:52:06 -040043import android.app.StatusBarManager;
44import android.content.BroadcastReceiver;
Jorim Jaggi786afcb2014-09-25 02:41:29 +020045import android.content.ComponentCallbacks2;
Jason Monk7e53f202016-01-28 10:40:20 -050046import android.content.ComponentName;
Joe Onorato808182d2010-07-09 18:52:06 -040047import android.content.Context;
48import android.content.Intent;
49import android.content.IntentFilter;
Ricky Waicd35def2016-05-03 11:07:07 +010050import android.content.IntentSender;
Adrian Roos21d2a252015-06-01 13:59:59 -070051import android.content.pm.IPackageManager;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -070052import android.content.pm.PackageManager;
Tony Mak92c989d2016-04-19 14:02:44 +010053import android.content.pm.UserInfo;
Daniel Sandler777dcde2013-09-30 10:21:45 -040054import android.content.res.Configuration;
Michael Jurka7f2668c2012-03-27 07:49:52 -070055import android.content.res.Resources;
John Spurlock919adac2012-10-02 16:41:12 -040056import android.database.ContentObserver;
Dan Sandler16128f42014-05-21 12:48:22 -040057import android.graphics.Bitmap;
Romain Guy648342f2012-05-25 10:44:45 -070058import android.graphics.Canvas;
59import android.graphics.ColorFilter;
Joe Onorato808182d2010-07-09 18:52:06 -040060import android.graphics.PixelFormat;
Daniel Sandlere680f542012-09-28 12:22:27 -040061import android.graphics.Point;
Jorim Jaggi2a5e4522014-11-24 21:45:20 +010062import android.graphics.PointF;
Romain Guy648342f2012-05-25 10:44:45 -070063import android.graphics.PorterDuff;
Selim Cineka0fad3b2014-09-19 17:20:05 +020064import android.graphics.PorterDuffXfermode;
Joe Onorato808182d2010-07-09 18:52:06 -040065import android.graphics.Rect;
Adrian Roos3b777cb2016-04-14 12:04:28 -070066import android.graphics.drawable.BitmapDrawable;
Dan Sandler16128f42014-05-21 12:48:22 -040067import android.graphics.drawable.ColorDrawable;
Romain Guy648342f2012-05-25 10:44:45 -070068import android.graphics.drawable.Drawable;
Michael Jurka7f2668c2012-03-27 07:49:52 -070069import android.inputmethodservice.InputMethodService;
John Spurlock7b414672014-07-18 13:02:39 -040070import android.media.AudioAttributes;
Dan Sandler16128f42014-05-21 12:48:22 -040071import android.media.MediaMetadata;
72import android.media.session.MediaController;
73import android.media.session.MediaSession;
74import android.media.session.MediaSessionManager;
75import android.media.session.PlaybackState;
Adrian Roos7bb38a92016-07-21 11:44:01 -070076import android.net.Uri;
Selim Cinekbaa23272014-07-08 18:01:07 +020077import android.os.AsyncTask;
John Spurlock3c875662013-08-31 15:07:25 -040078import android.os.Bundle;
John Spurlock919adac2012-10-02 16:41:12 -040079import android.os.Handler;
Jason Monk4ae97d32014-12-17 10:14:33 -050080import android.os.HandlerThread;
Joe Onorato808182d2010-07-09 18:52:06 -040081import android.os.IBinder;
Joe Onorato808182d2010-07-09 18:52:06 -040082import android.os.Message;
John Spurlock56d007b2013-10-28 18:40:56 -040083import android.os.PowerManager;
Jason Monk4ae97d32014-12-17 10:14:33 -050084import android.os.Process;
Michael Jurka7f2668c2012-03-27 07:49:52 -070085import android.os.RemoteException;
Adrian Roos21d2a252015-06-01 13:59:59 -070086import android.os.ServiceManager;
Joe Onorato808182d2010-07-09 18:52:06 -040087import android.os.SystemClock;
Nick Desaulniers1d396752016-07-25 15:05:33 -070088import android.os.Trace;
Adrian Roos7bb38a92016-07-21 11:44:01 -070089import android.os.SystemProperties;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070090import android.os.UserHandle;
Adrian Roos2b154a92014-11-17 15:18:39 +010091import android.os.UserManager;
Selim Cinek69ff8af2015-08-25 19:03:48 -070092import android.os.Vibrator;
Daniel Sandlerd3090562011-08-09 00:28:44 -040093import android.provider.Settings;
Chris Wren3ad4e3a2014-09-02 17:23:51 -040094import android.service.notification.NotificationListenerService;
Christoph Studerd0694b62014-06-04 16:36:01 +020095import android.service.notification.NotificationListenerService.RankingMap;
John Spurlockde84f0e2013-06-12 12:41:00 -040096import android.service.notification.StatusBarNotification;
Selim Cinek64be7722016-07-22 13:28:16 -070097import android.telecom.TelecomManager;
Christoph Studer92b389d2014-04-01 18:44:40 +020098import android.util.ArraySet;
Daniel Sandler36412a72011-08-04 09:35:13 -040099import android.util.DisplayMetrics;
Chris Wren64161cc2012-12-17 16:49:30 -0500100import android.util.EventLog;
Joe Onorato808182d2010-07-09 18:52:06 -0400101import android.util.Log;
102import android.view.Display;
Adrian Roosa98b32c2016-08-11 10:41:08 -0700103import android.view.IRotationWatcher;
Jorim Jaggidf993512014-05-13 23:06:35 +0200104import android.view.KeyEvent;
Jorim Jaggid4a57442014-04-10 02:45:55 +0200105import android.view.LayoutInflater;
Joe Onorato808182d2010-07-09 18:52:06 -0400106import android.view.MotionEvent;
Chris Craik2507c342015-05-04 14:36:49 -0700107import android.view.ThreadedRenderer;
Joe Onorato808182d2010-07-09 18:52:06 -0400108import android.view.View;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800109import android.view.ViewGroup;
Jim Millerf2a16b22011-07-06 17:32:48 -0700110import android.view.ViewGroup.LayoutParams;
Selim Cinek3e7592d2016-04-11 09:35:54 +0800111import android.view.ViewParent;
Dan Sandler44c0dfd2014-06-09 11:26:16 -0400112import android.view.ViewStub;
Ricky Waicd35def2016-05-03 11:07:07 +0100113import android.view.ViewTreeObserver;
Joe Onorato808182d2010-07-09 18:52:06 -0400114import android.view.WindowManager;
Jorim Jaggi786afcb2014-09-25 02:41:29 +0200115import android.view.WindowManagerGlobal;
Jorim Jaggi4e723e62016-12-14 11:02:39 -0800116import android.view.accessibility.AccessibilityEvent;
Daniel Sandlerd7e96862012-04-26 01:10:29 -0400117import android.view.animation.AccelerateInterpolator;
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200118import android.view.animation.Interpolator;
Dan Sandler16128f42014-05-21 12:48:22 -0400119import android.widget.ImageView;
Joe Onorato808182d2010-07-09 18:52:06 -0400120import android.widget.TextView;
Selim Cinek64be7722016-07-22 13:28:16 -0700121
Chris Wren9763d422015-04-30 15:24:05 -0400122import com.android.internal.logging.MetricsLogger;
Chris Wrenf6e9228b2016-01-26 18:04:35 -0500123import com.android.internal.logging.MetricsProto.MetricsEvent;
Chris Wrend1dbc922015-06-19 17:51:16 -0400124import com.android.internal.statusbar.NotificationVisibility;
Joe Onorato808182d2010-07-09 18:52:06 -0400125import com.android.internal.statusbar.StatusBarIcon;
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +0100126import com.android.keyguard.KeyguardHostView.OnDismissAction;
Jason Monkab525272015-07-13 17:02:49 -0400127import com.android.keyguard.KeyguardUpdateMonitor;
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700128import com.android.keyguard.KeyguardUpdateMonitorCallback;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200129import com.android.keyguard.ViewMediatorCallback;
Clara Bayarri9b1fdff2016-04-21 14:28:47 +0100130import com.android.systemui.AutoReinflateContainer;
131import com.android.systemui.AutoReinflateContainer.InflateListener;
Jorim Jaggi708f7722014-08-20 17:30:38 +0200132import com.android.systemui.BatteryMeterView;
John Spurlock3c875662013-08-31 15:07:25 -0400133import com.android.systemui.DemoMode;
Christoph Studerb0183992014-12-22 21:02:26 +0100134import com.android.systemui.EventLogConstants;
Chris Wren64161cc2012-12-17 16:49:30 -0500135import com.android.systemui.EventLogTags;
Winsonc0d70582016-01-29 10:24:39 -0800136import com.android.systemui.Interpolators;
Andrew Flynn82862572015-04-01 14:22:37 -0400137import com.android.systemui.Prefs;
Joe Onorato808182d2010-07-09 18:52:06 -0400138import com.android.systemui.R;
Xiaohui Chen5da71352016-02-22 10:04:41 -0800139import com.android.systemui.SystemUIFactory;
Adrian Roos401caae2016-03-04 13:35:21 -0800140import com.android.systemui.classifier.FalsingLog;
Selim Cinek5f71bee2015-11-18 10:25:23 -0800141import com.android.systemui.classifier.FalsingManager;
Jeff Brown4d69e222014-09-18 15:27:50 -0700142import com.android.systemui.doze.DozeHost;
John Spurlock813552c2014-09-19 08:30:21 -0400143import com.android.systemui.doze.DozeLog;
Jorim Jaggicff0acb2014-03-31 16:35:15 +0200144import com.android.systemui.keyguard.KeyguardViewMediator;
Jason Monk162011e2016-02-19 08:11:55 -0500145import com.android.systemui.qs.QSContainer;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400146import com.android.systemui.qs.QSPanel;
Jorim Jaggid61f2272014-12-19 20:35:35 +0100147import com.android.systemui.recents.ScreenPinningRequest;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800148import com.android.systemui.recents.events.EventBus;
Jorim Jaggi2adba072016-03-03 13:43:39 +0100149import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800150import com.android.systemui.recents.events.activity.UndockingTaskEvent;
Jorim Jaggidd98d412015-11-18 15:57:38 -0800151import com.android.systemui.stackdivider.Divider;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800152import com.android.systemui.stackdivider.WindowManagerProxy;
Selim Cineka32ab602014-06-11 15:06:01 +0200153import com.android.systemui.statusbar.ActivatableNotificationView;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200154import com.android.systemui.statusbar.BackDropView;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500155import com.android.systemui.statusbar.BaseStatusBar;
Michael Jurkaa600fd92012-06-25 15:57:05 -0700156import com.android.systemui.statusbar.CommandQueue;
Dan Sandlereceda3d2014-07-21 15:35:01 -0400157import com.android.systemui.statusbar.DismissView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200158import com.android.systemui.statusbar.DragDownHelper;
Jorim Jaggia2052ea2014-08-05 16:22:30 +0200159import com.android.systemui.statusbar.EmptyShadeView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200160import com.android.systemui.statusbar.ExpandableNotificationRow;
Daniel Sandler33805342012-07-23 15:45:12 -0400161import com.android.systemui.statusbar.GestureRecorder;
Andrei Stingaceanuf86bc972016-04-12 15:29:25 +0100162import com.android.systemui.statusbar.KeyboardShortcuts;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200163import com.android.systemui.statusbar.KeyguardIndicationController;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700164import com.android.systemui.statusbar.NotificationData;
Daniel Sandler58b173b2012-05-03 11:25:29 -0400165import com.android.systemui.statusbar.NotificationData.Entry;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200166import com.android.systemui.statusbar.NotificationOverflowContainer;
Adrian Roos1c0ca502015-10-07 12:20:42 -0700167import com.android.systemui.statusbar.RemoteInputController;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200168import com.android.systemui.statusbar.ScrimView;
Christian Robertson2e347422011-08-11 14:01:04 -0700169import com.android.systemui.statusbar.SignalClusterView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200170import com.android.systemui.statusbar.StatusBarState;
Selim Cinekadd95262016-12-06 14:34:47 -0800171import com.android.systemui.statusbar.notification.VisualStabilityManager;
Christoph Studer2231c6e2014-12-19 12:40:13 +0100172import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200173import com.android.systemui.statusbar.policy.AccessibilityController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400174import com.android.systemui.statusbar.policy.BatteryController;
John Spurlock0ff62e02014-07-22 16:15:08 -0400175import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700176import com.android.systemui.statusbar.policy.BatteryControllerImpl;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400177import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200178import com.android.systemui.statusbar.policy.BrightnessMirrorController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400179import com.android.systemui.statusbar.policy.CastControllerImpl;
Adrian Roos316bf542016-08-23 17:53:07 +0200180import com.android.systemui.statusbar.policy.EncryptionHelper;
Adrian Roosb83777b2014-06-30 15:11:53 +0200181import com.android.systemui.statusbar.policy.FlashlightController;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700182import com.android.systemui.statusbar.policy.HeadsUpManager;
Jason Monk3d5f5512014-07-25 11:17:28 -0400183import com.android.systemui.statusbar.policy.HotspotControllerImpl;
Jorim Jaggi4e723e62016-12-14 11:02:39 -0800184import com.android.systemui.statusbar.policy.KeyButtonView;
John Spurlock657c62c2014-07-22 12:18:09 -0400185import com.android.systemui.statusbar.policy.KeyguardMonitor;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700186import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400187import com.android.systemui.statusbar.policy.LocationControllerImpl;
Adrian Roos316bf542016-08-23 17:53:07 +0200188import com.android.systemui.statusbar.policy.NetworkController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400189import com.android.systemui.statusbar.policy.NetworkControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400190import com.android.systemui.statusbar.policy.NextAlarmController;
Selim Cinekadd95262016-12-06 14:34:47 -0800191import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
Jorim Jaggi85dc23c2014-09-08 14:42:29 +0200192import com.android.systemui.statusbar.policy.PreviewInflater;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400193import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400194import com.android.systemui.statusbar.policy.SecurityControllerImpl;
195import com.android.systemui.statusbar.policy.UserInfoController;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200196import com.android.systemui.statusbar.policy.UserSwitcherController;
John Spurlock86005342014-05-23 11:58:00 -0400197import com.android.systemui.statusbar.policy.ZenModeController;
Selim Cinek67b22602014-03-10 15:40:16 +0100198import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
Selim Cinek64be7722016-07-22 13:28:16 -0700199import com.android.systemui.statusbar.stack.NotificationStackScrollLayout
200 .OnChildLocationsChangedListener;
Jorim Jaggi37c11802015-08-18 20:27:54 -0700201import com.android.systemui.statusbar.stack.StackStateAnimator;
John Spurlock86005342014-05-23 11:58:00 -0400202import com.android.systemui.volume.VolumeComponent;
Selim Cinek67b22602014-03-10 15:40:16 +0100203
Daniel Sandler6a858c32012-03-12 14:38:58 -0400204import java.io.FileDescriptor;
205import java.io.PrintWriter;
Adrian Roos7bb38a92016-07-21 11:44:01 -0700206import java.io.StringWriter;
Daniel Sandler6a858c32012-03-12 14:38:58 -0400207import java.util.ArrayList;
Christoph Studer92b389d2014-04-01 18:44:40 +0200208import java.util.Collection;
209import java.util.Collections;
Selim Cinekb5605e52015-02-20 18:21:41 +0100210import java.util.HashMap;
Dan Sandler16128f42014-05-21 12:48:22 -0400211import java.util.List;
John Spurlock7bbb9f62014-10-21 12:15:28 -0400212import java.util.Map;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700213
Jorim Jaggiecbab362014-04-23 16:13:15 +0200214public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Selim Cinek8d490d42015-04-10 00:05:50 -0700215 DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
Selim Cinekadd95262016-12-06 14:34:47 -0800216 OnHeadsUpChangedListener, VisualStabilityManager.Callback {
Joe Onoratofd52b182010-11-10 18:00:52 -0800217 static final String TAG = "PhoneStatusBar";
Daniel Sandler198a0302012-08-17 16:04:31 -0400218 public static final boolean DEBUG = BaseStatusBar.DEBUG;
Chris Wren6d15a362013-08-20 18:46:29 -0400219 public static final boolean SPEW = false;
Daniel Sandler7579bca2011-08-18 15:47:26 -0400220 public static final boolean DUMPTRUCK = true; // extra dumpsys info
Daniel Sandlerfa027f52013-04-11 22:01:47 -0400221 public static final boolean DEBUG_GESTURES = false;
Dan Sandler16128f42014-05-21 12:48:22 -0400222 public static final boolean DEBUG_MEDIA = false;
223 public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
Joe Onorato808182d2010-07-09 18:52:06 -0400224
John Spurlock342cad72013-10-08 09:36:50 -0400225 public static final boolean DEBUG_WINDOW_STATE = false;
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400226
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400227 // additional instrumentation for testing purposes; intended to be left on during development
Daniel Sandler7c351742011-10-17 10:48:06 -0400228 public static final boolean CHATTY = DEBUG;
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400229
Dan Sandler16128f42014-05-21 12:48:22 -0400230 public static final boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
231
Adrian Roos8e3e8362015-07-16 19:42:22 -0700232 public static final String ACTION_FAKE_ARTWORK = "fake_artwork";
233
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400234 private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
Daniel Sandler11cf1782012-09-27 14:03:08 -0400235 private static final int MSG_CLOSE_PANELS = 1001;
236 private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
Jorim Jaggi826730a2014-12-08 21:05:13 +0100237 private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
Winson Chungb1f74992014-08-08 12:53:09 -0700238 // 1020-1040 reserved for BaseStatusBar
Joe Onorato808182d2010-07-09 18:52:06 -0400239
Jorim Jaggi826730a2014-12-08 21:05:13 +0100240 // Time after we abort the launch transition.
241 private static final long LAUNCH_TRANSITION_TIMEOUT_MS = 5000;
242
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400243 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
244
John Spurlocke1f366f2013-08-05 12:22:40 -0400245 private static final int STATUS_OR_NAV_TRANSIENT =
246 View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
John Spurlock32beb2c2013-03-11 10:16:47 -0400247 private static final long AUTOHIDE_TIMEOUT_MS = 3000;
John Spurlocke1f366f2013-08-05 12:22:40 -0400248
Christoph Studer92b389d2014-04-01 18:44:40 +0200249 /** The minimum delay in ms between reports of notification visibility. */
250 private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
251
Jorim Jaggi93a2bb22014-06-02 19:57:28 +0200252 /**
253 * The delay to reset the hint text when the hint animation is finished running.
254 */
255 private static final int HINT_RESET_DELAY_MS = 1200;
256
John Spurlock7b414672014-07-18 13:02:39 -0400257 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
258 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
259 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
260 .build();
261
Selim Cinekbaa23272014-07-08 18:01:07 +0200262 public static final int FADE_KEYGUARD_START_DELAY = 100;
263 public static final int FADE_KEYGUARD_DURATION = 300;
Jorim Jaggi90978852015-08-18 19:55:53 -0700264 public static final int FADE_KEYGUARD_DURATION_PULSING = 96;
Selim Cinekbaa23272014-07-08 18:01:07 +0200265
Jason Monk815e0572014-08-12 17:26:36 -0400266 /** Allow some time inbetween the long press for back and recents. */
267 private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
268
Adrian Roos2f2bd9a2015-06-04 18:11:14 -0700269 /** If true, the system is in the half-boot-to-decryption-screen state.
270 * Prudently disable QS and notifications. */
Adrian Roos21d2a252015-06-01 13:59:59 -0700271 private static final boolean ONLY_CORE_APPS;
272
Adrian Roos52738322016-01-29 08:49:21 -0800273 /** If true, the lockscreen will show a distinct wallpaper */
Adrian Roose381c162016-02-11 15:26:42 -0800274 private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
Adrian Roos52738322016-01-29 08:49:21 -0800275
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700276 /* If true, the device supports freeform window management.
277 * This affects the status bar UI. */
278 private static final boolean FREEFORM_WINDOW_MANAGEMENT;
279
Adrian Roos18d099a2016-05-19 15:28:18 -0700280 /**
281 * How long to wait before auto-dismissing a notification that was kept for remote input, and
282 * has now sent a remote input. We auto-dismiss, because the app may not see a reason to cancel
283 * these given that they technically don't exist anymore. We wait a bit in case the app issues
284 * an update.
285 */
286 private static final int REMOTE_INPUT_KEPT_ENTRY_AUTO_CANCEL_DELAY = 200;
287
Jorim Jaggi6626f542016-08-22 13:08:44 -0700288 /**
289 * Never let the alpha become zero for surfaces that draw with SRC - otherwise the RenderNode
290 * won't draw anything and uninitialized memory will show through
291 * if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in
292 * libhwui.
293 */
294 private static final float SRC_MIN_ALPHA = 0.002f;
295
Adrian Roos21d2a252015-06-01 13:59:59 -0700296 static {
297 boolean onlyCoreApps;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700298 boolean freeformWindowManagement;
Adrian Roos21d2a252015-06-01 13:59:59 -0700299 try {
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700300 IPackageManager packageManager =
301 IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
302 onlyCoreApps = packageManager.isOnlyCoreApps();
303 freeformWindowManagement = packageManager.hasSystemFeature(
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700304 PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT, 0);
Adrian Roos21d2a252015-06-01 13:59:59 -0700305 } catch (RemoteException e) {
306 onlyCoreApps = false;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700307 freeformWindowManagement = false;
Adrian Roos21d2a252015-06-01 13:59:59 -0700308 }
309 ONLY_CORE_APPS = onlyCoreApps;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700310 FREEFORM_WINDOW_MANAGEMENT = freeformWindowManagement;
Adrian Roos21d2a252015-06-01 13:59:59 -0700311 }
312
Joe Onoratofd52b182010-11-10 18:00:52 -0800313 PhoneStatusBarPolicy mIconPolicy;
Joe Onorato808182d2010-07-09 18:52:06 -0400314
Daniel Sandler2b697352011-07-22 16:23:09 -0400315 // These are no longer handled by the policy, because we need custom strategies for them
John Spurlockaf8d6c42014-05-07 17:49:08 -0400316 BluetoothControllerImpl mBluetoothController;
Jason Monk3d5f5512014-07-25 11:17:28 -0400317 SecurityControllerImpl mSecurityController;
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -0800318 protected BatteryController mBatteryController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400319 LocationControllerImpl mLocationController;
320 NetworkControllerImpl mNetworkController;
Jason Monk51e4dc02014-07-22 12:00:47 -0400321 HotspotControllerImpl mHotspotController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400322 RotationLockControllerImpl mRotationLockController;
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200323 UserInfoController mUserInfoController;
Muyuan Li40e11352016-03-23 11:43:58 -0700324 protected ZenModeController mZenModeController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400325 CastControllerImpl mCastController;
John Spurlock86005342014-05-23 11:58:00 -0400326 VolumeComponent mVolumeComponent;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700327 KeyguardUserSwitcher mKeyguardUserSwitcher;
Adrian Roosb83777b2014-06-30 15:11:53 +0200328 FlashlightController mFlashlightController;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800329 protected UserSwitcherController mUserSwitcherController;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200330 NextAlarmController mNextAlarmController;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800331 protected KeyguardMonitor mKeyguardMonitor;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200332 BrightnessMirrorController mBrightnessMirrorController;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200333 AccessibilityController mAccessibilityController;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700334 FingerprintUnlockController mFingerprintUnlockController;
Jorim Jaggi86905582016-02-09 21:36:09 -0800335 LightStatusBarController mLightStatusBarController;
Vadim Tryshev12a30e82016-02-12 15:39:28 -0800336 protected LockscreenWallpaper mLockscreenWallpaper;
Jim Miller5e6af442011-12-02 18:24:26 -0800337
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400338 int mNaturalBarHeight = -1;
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100339
Joe Onorato808182d2010-07-09 18:52:06 -0400340 Display mDisplay;
Daniel Sandlere680f542012-09-28 12:22:27 -0400341 Point mCurrentDisplaySize = new Point();
Joe Onorato808182d2010-07-09 18:52:06 -0400342
Xiaohui Chend839d1a2016-01-21 13:05:02 -0800343 protected StatusBarWindowView mStatusBarWindow;
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700344 protected PhoneStatusBarView mStatusBarView;
John Spurlockd4e65752013-08-28 14:17:09 -0400345 private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800346 protected StatusBarWindowManager mStatusBarWindowManager;
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200347 private UnlockMethodCache mUnlockMethodCache;
John Spurlockbf370992014-06-17 13:58:31 -0400348 private DozeServiceHost mDozeServiceHost;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -0700349 private boolean mWakeUpComingFromTouch;
350 private PointF mWakeUpTouchLocation;
Selim Cinek1b6f8192015-09-03 16:01:53 -0700351 private boolean mScreenTurningOn;
Daniel Sandlera310af82012-04-24 01:20:13 -0400352
Joe Onorato808182d2010-07-09 18:52:06 -0400353 int mPixelFormat;
Joe Onorato808182d2010-07-09 18:52:06 -0400354 Object mQueueLock = new Object();
355
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700356 protected StatusBarIconController mIconController;
Joe Onorato808182d2010-07-09 18:52:06 -0400357
358 // expanded notifications
Xiaohui Chenea4b6ba2016-02-18 10:53:17 -0800359 protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
Joe Onorato808182d2010-07-09 18:52:06 -0400360 View mExpandedContents;
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400361 TextView mNotificationPanelDebugText;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400362
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400363 // settings
John Spurlockaf8d6c42014-05-07 17:49:08 -0400364 private QSPanel mQSPanel;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400365
Joe Onorato808182d2010-07-09 18:52:06 -0400366 // top bar
Jason Monk0e1101d2015-10-07 13:06:09 -0400367 BaseStatusBarHeader mHeader;
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700368 protected KeyguardStatusBarView mKeyguardStatusBar;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200369 View mKeyguardStatusView;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200370 KeyguardBottomAreaView mKeyguardBottomArea;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200371 boolean mLeaveOpenOnKeyguardHide;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200372 KeyguardIndicationController mKeyguardIndicationController;
Jorim Jaggie70d31f2014-04-24 22:08:30 +0200373
Adrian Roos46df1ca2015-09-11 12:38:43 -0700374 // Keyguard is going away soon.
375 private boolean mKeyguardGoingAway;
376 // Keyguard is actually fading away now.
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700377 private boolean mKeyguardFadingAway;
378 private long mKeyguardFadingAwayDelay;
379 private long mKeyguardFadingAwayDuration;
380
Adrian Roos3aec6382016-02-05 14:19:01 -0800381 // RemoteInputView to be activated after unlock
382 private View mPendingRemoteInputView;
Ricky Waicd35def2016-05-03 11:07:07 +0100383 private View mPendingWorkRemoteInputView;
Adrian Roos3aec6382016-02-05 14:19:01 -0800384
Adrian Roos7bb38a92016-07-21 11:44:01 -0700385 private View mReportRejectedTouch;
386
Selim Cinek5f71bee2015-11-18 10:25:23 -0800387 int mMaxAllowedKeyguardNotifications;
Daniel Sandlerd3090562011-08-09 00:28:44 -0400388
Joe Onorato808182d2010-07-09 18:52:06 -0400389 boolean mExpandedVisible;
390
John Spurlockd4e65752013-08-28 14:17:09 -0400391 private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400392
Joe Onorato808182d2010-07-09 18:52:06 -0400393 // the tracker view
Joe Onorato808182d2010-07-09 18:52:06 -0400394 int mTrackingPosition; // the position of the top of the tracking view.
Joe Onorato808182d2010-07-09 18:52:06 -0400395
Joe Onorato808182d2010-07-09 18:52:06 -0400396 // Tracking finger for opening/closing.
Joe Onorato808182d2010-07-09 18:52:06 -0400397 boolean mTracking;
Joe Onorato808182d2010-07-09 18:52:06 -0400398
Joe Onorato808182d2010-07-09 18:52:06 -0400399 int[] mAbsPos = new int[2];
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200400 ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
Chet Haase2f2022a2011-10-11 06:41:59 -0700401
Joe Onorato808182d2010-07-09 18:52:06 -0400402 // for disabling the status bar
Benjamin Franzcde0a2a2015-04-23 17:19:48 +0100403 int mDisabled1 = 0;
404 int mDisabled2 = 0;
Joe Onorato808182d2010-07-09 18:52:06 -0400405
Daniel Sandler60ee2562011-07-22 12:34:33 -0400406 // tracking calls to View.setSystemUiVisibility()
407 int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
Jorim Jaggi86905582016-02-09 21:36:09 -0800408 private final Rect mLastFullscreenStackBounds = new Rect();
409 private final Rect mLastDockedStackBounds = new Rect();
Daniel Sandler60ee2562011-07-22 12:34:33 -0400410
Adrian Roos389beec2015-05-12 13:33:25 -0700411 // last value sent to window manager
412 private int mLastDispatchedSystemUiVisibility = ~View.SYSTEM_UI_FLAG_VISIBLE;
413
Daniel Sandler36412a72011-08-04 09:35:13 -0400414 DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700415
Daniel Sandler33805342012-07-23 15:45:12 -0400416 // XXX: gesture research
Daniel Sandler151f00d2012-10-02 22:33:08 -0400417 private final GestureRecorder mGestureRec = DEBUG_GESTURES
John Spurlock209bede2013-07-17 12:23:27 -0400418 ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
Daniel Sandler151f00d2012-10-02 22:33:08 -0400419 : null;
Daniel Sandler33805342012-07-23 15:45:12 -0400420
Jason Monk18f99d92014-09-11 13:36:42 -0400421 private ScreenPinningRequest mScreenPinningRequest;
422
Daniel Sandler328310c2011-09-23 15:56:52 -0400423 private int mNavigationIconHints = 0;
Jason Monk4ae97d32014-12-17 10:14:33 -0500424 private HandlerThread mHandlerThread;
Daniel Sandler328310c2011-09-23 15:56:52 -0400425
John Spurlock919adac2012-10-02 16:41:12 -0400426 // ensure quick settings is disabled until the current user makes it through the setup wizard
427 private boolean mUserSetup = false;
428 private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
429 @Override
430 public void onChange(boolean selfChange) {
431 final boolean userSetup = 0 != Settings.Secure.getIntForUser(
432 mContext.getContentResolver(),
433 Settings.Secure.USER_SETUP_COMPLETE,
434 0 /*default */,
435 mCurrentUserId);
John Spurlockcd686b52013-06-05 10:13:46 -0400436 if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
John Spurlocke4e8c562012-10-04 09:55:01 -0400437 "selfChange=%s userSetup=%s mUserSetup=%s",
438 selfChange, userSetup, mUserSetup));
John Spurlock73203eb2014-04-15 16:14:46 -0400439
John Spurlock919adac2012-10-02 16:41:12 -0400440 if (userSetup != mUserSetup) {
441 mUserSetup = userSetup;
John Spurlock919adac2012-10-02 16:41:12 -0400442 if (!mUserSetup && mStatusBarView != null)
443 animateCollapseQuickSettings();
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700444 if (mKeyguardBottomArea != null) {
445 mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
446 }
Jason Monkfd57ea72016-04-29 13:37:58 -0400447 if (mNetworkController != null) {
448 mNetworkController.setUserSetupComplete(mUserSetup);
449 }
John Spurlock919adac2012-10-02 16:41:12 -0400450 }
John Spurlock604a5ee2015-06-01 12:27:22 -0400451 if (mIconPolicy != null) {
452 mIconPolicy.setCurrentUserSetup(mUserSetup);
453 }
John Spurlock919adac2012-10-02 16:41:12 -0400454 }
455 };
456
Chris Wrenf6e83f42013-09-11 14:02:59 -0400457 final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
458 @Override
459 public void onChange(boolean selfChange) {
460 boolean wasUsing = mUseHeadsUp;
Jason Monkf7019542014-07-31 12:42:25 -0400461 mUseHeadsUp = ENABLE_HEADS_UP && !mDisableNotificationAlerts
462 && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
Chris Wren10d82df2014-03-01 10:34:51 -0500463 mContext.getContentResolver(), Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Chris Wren7bd241232014-02-28 16:25:05 -0500464 Settings.Global.HEADS_UP_OFF);
Chris Wren22ae46e2014-02-26 18:08:09 -0500465 mHeadsUpTicker = mUseHeadsUp && 0 != Settings.Global.getInt(
466 mContext.getContentResolver(), SETTING_HEADS_UP_TICKER, 0);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400467 Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
468 if (wasUsing != mUseHeadsUp) {
469 if (!mUseHeadsUp) {
470 Log.d(TAG, "dismissing any existing heads up notification on disable event");
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700471 mHeadsUpManager.releaseAllImmediately();
Chris Wrenf6e83f42013-09-11 14:02:59 -0400472 }
473 }
474 }
475 };
476
John Spurlockcfc359a2013-09-05 10:42:03 -0400477 private int mInteractingWindows;
John Spurlock32beb2c2013-03-11 10:16:47 -0400478 private boolean mAutohideSuspended;
John Spurlockd4e65752013-08-28 14:17:09 -0400479 private int mStatusBarMode;
480 private int mNavigationBarMode;
Selim Cinek5f71bee2015-11-18 10:25:23 -0800481 private int mMaxKeyguardNotifications;
Jorim Jaggid41083a2014-09-12 02:54:40 +0200482
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200483 private ViewMediatorCallback mKeyguardViewMediatorCallback;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800484 protected ScrimController mScrimController;
485 protected DozeScrimController mDozeScrimController;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200486
John Spurlock32beb2c2013-03-11 10:16:47 -0400487 private final Runnable mAutohide = new Runnable() {
488 @Override
489 public void run() {
John Spurlocke1f366f2013-08-05 12:22:40 -0400490 int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT;
John Spurlock9deaa282013-07-25 13:03:47 -0400491 if (mSystemUiVisibility != requested) {
492 notifyUiVisibilityChanged(requested);
493 }
John Spurlock32beb2c2013-03-11 10:16:47 -0400494 }};
495
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700496 private boolean mWaitingForKeyguardExit;
John Spurlockbf370992014-06-17 13:58:31 -0400497 private boolean mDozing;
Jorim Jaggi83969702015-06-05 14:59:24 -0700498 private boolean mDozingRequested;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800499 protected boolean mScrimSrcModeEnabled;
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100500
Selim Cinekc18010f2016-01-20 13:41:30 -0800501 public static final Interpolator ALPHA_IN = Interpolators.ALPHA_IN;
502 public static final Interpolator ALPHA_OUT = Interpolators.ALPHA_OUT;
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200503
Selim Cineka0fad3b2014-09-19 17:20:05 +0200504 private BackDropView mBackdrop;
Dan Sandler16128f42014-05-21 12:48:22 -0400505 private ImageView mBackdropFront, mBackdropBack;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200506 private PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
507 private PorterDuffXfermode mSrcOverXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);
Dan Sandler16128f42014-05-21 12:48:22 -0400508
509 private MediaSessionManager mMediaSessionManager;
510 private MediaController mMediaController;
511 private String mMediaNotificationKey;
512 private MediaMetadata mMediaMetadata;
513 private MediaController.Callback mMediaListener
514 = new MediaController.Callback() {
515 @Override
516 public void onPlaybackStateChanged(PlaybackState state) {
517 super.onPlaybackStateChanged(state);
518 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onPlaybackStateChanged: " + state);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -0400519 if (state != null) {
520 if (!isPlaybackActive(state.getState())) {
521 clearCurrentMediaNotification();
Adrian Roos52738322016-01-29 08:49:21 -0800522 updateMediaMetaData(true, true);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -0400523 }
524 }
Dan Sandler16128f42014-05-21 12:48:22 -0400525 }
526
527 @Override
528 public void onMetadataChanged(MediaMetadata metadata) {
529 super.onMetadataChanged(metadata);
530 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onMetadataChanged: " + metadata);
531 mMediaMetadata = metadata;
Adrian Roos52738322016-01-29 08:49:21 -0800532 updateMediaMetaData(true, true);
Dan Sandler16128f42014-05-21 12:48:22 -0400533 }
534 };
535
536 private final OnChildLocationsChangedListener mOnChildLocationsChangedListener =
537 new OnChildLocationsChangedListener() {
538 @Override
539 public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout) {
540 userActivity();
541 }
542 };
543
Benjamin Franzcde0a2a2015-04-23 17:19:48 +0100544 private int mDisabledUnmodified1;
545 private int mDisabledUnmodified2;
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200546
Christoph Studer92b389d2014-04-01 18:44:40 +0200547 /** Keys of notifications currently visible to the user. */
Chris Wrend1dbc922015-06-19 17:51:16 -0400548 private final ArraySet<NotificationVisibility> mCurrentlyVisibleNotifications =
549 new ArraySet<>();
Christoph Studer92b389d2014-04-01 18:44:40 +0200550 private long mLastVisibilityReportUptimeMs;
551
John Spurlockbf370992014-06-17 13:58:31 -0400552 private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
553
Selim Cinekbaa23272014-07-08 18:01:07 +0200554 private Runnable mLaunchTransitionEndRunnable;
555 private boolean mLaunchTransitionFadingAway;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +0200556 private ExpandableNotificationRow mDraggedDownRow;
Selim Cinek372d1bd2015-08-14 13:19:37 -0700557 private boolean mLaunchCameraOnScreenTurningOn;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -0700558 private boolean mLaunchCameraOnFinishedGoingToSleep;
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700559 private int mLastCameraLaunchSource;
Selim Cinek372d1bd2015-08-14 13:19:37 -0700560 private PowerManager.WakeLock mGestureWakeLock;
Selim Cinek69ff8af2015-08-25 19:03:48 -0700561 private Vibrator mVibrator;
Jorim Jaggi362dd6d2014-07-09 19:04:07 +0200562
Christoph Studer2231c6e2014-12-19 12:40:13 +0100563 // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
564 private int mLastLoggedStateFingerprint;
565
Jorim Jaggi18f18ae2015-09-10 15:48:21 -0700566 /**
567 * If set, the device has started going to sleep but isn't fully non-interactive yet.
568 */
569 protected boolean mStartedGoingToSleep;
570
Christoph Studer92b389d2014-04-01 18:44:40 +0200571 private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
572 new OnChildLocationsChangedListener() {
573 @Override
574 public void onChildLocationsChanged(
575 NotificationStackScrollLayout stackScrollLayout) {
576 if (mHandler.hasCallbacks(mVisibilityReporter)) {
577 // Visibilities will be reported when the existing
578 // callback is executed.
579 return;
580 }
581 // Calculate when we're allowed to run the visibility
582 // reporter. Note that this timestamp might already have
583 // passed. That's OK, the callback will just be executed
584 // ASAP.
585 long nextReportUptimeMs =
586 mLastVisibilityReportUptimeMs + VISIBILITY_REPORT_MIN_DELAY_MS;
587 mHandler.postAtTime(mVisibilityReporter, nextReportUptimeMs);
588 }
589 };
590
591 // Tracks notifications currently visible in mNotificationStackScroller and
592 // emits visibility events via NoMan on changes.
593 private final Runnable mVisibilityReporter = new Runnable() {
Chris Wrend1dbc922015-06-19 17:51:16 -0400594 private final ArraySet<NotificationVisibility> mTmpNewlyVisibleNotifications =
595 new ArraySet<>();
596 private final ArraySet<NotificationVisibility> mTmpCurrentlyVisibleNotifications =
597 new ArraySet<>();
598 private final ArraySet<NotificationVisibility> mTmpNoLongerVisibleNotifications =
599 new ArraySet<>();
Christoph Studer92b389d2014-04-01 18:44:40 +0200600
601 @Override
602 public void run() {
603 mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
Chris Wrend1dbc922015-06-19 17:51:16 -0400604 final String mediaKey = getCurrentMediaNotificationKey();
Christoph Studer92b389d2014-04-01 18:44:40 +0200605
606 // 1. Loop over mNotificationData entries:
607 // A. Keep list of visible notifications.
608 // B. Keep list of previously hidden, now visible notifications.
609 // 2. Compute no-longer visible notifications by removing currently
610 // visible notifications from the set of previously visible
611 // notifications.
612 // 3. Report newly visible and no-longer visible notifications.
613 // 4. Keep currently visible notifications for next report.
Christoph Studerc8db24b2014-07-25 17:50:30 +0200614 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
615 int N = activeNotifications.size();
Christoph Studer92b389d2014-04-01 18:44:40 +0200616 for (int i = 0; i < N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +0200617 Entry entry = activeNotifications.get(i);
Christoph Studer92b389d2014-04-01 18:44:40 +0200618 String key = entry.notification.getKey();
Selim Cinekadd95262016-12-06 14:34:47 -0800619 boolean isVisible = mStackScroller.isInVisibleLocation(entry.row);
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 Jaggi4e723e62016-12-14 11:02:39 -0800668 private long mLastLockToAppLongPress;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200669
Selim Cinek99415392016-09-09 14:58:41 -0700670 private KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
671 @Override
672 public void onDreamingStateChanged(boolean dreaming) {
673 if (dreaming) {
674 maybeEscalateHeadsUp();
675 }
676 }
677 };
678
Joe Onorato808182d2010-07-09 18:52:06 -0400679 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400680 public void start() {
681 mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
682 .getDefaultDisplay();
Daniel Sandler7e8ae502013-10-10 23:38:19 -0400683 updateDisplaySize();
Jorim Jaggi0e664392014-09-27 01:30:22 +0200684 mScrimSrcModeEnabled = mContext.getResources().getBoolean(
685 R.bool.config_status_bar_scrim_behind_use_src);
Adrian Roos75fa3852015-01-27 20:21:44 +0100686
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500687 super.start(); // calls createAndAddWindows()
Joe Onorato808182d2010-07-09 18:52:06 -0400688
Dan Sandler16128f42014-05-21 12:48:22 -0400689 mMediaSessionManager
690 = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
691 // TODO: use MediaSessionManager.SessionListener to hook us up to future updates
692 // in session state
693
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400694 addNavigationBar();
695
Joe Onorato808182d2010-07-09 18:52:06 -0400696 // Lastly, call to the icon policy to install/update all the icons.
Jason Monk07473ce2016-01-05 14:59:19 -0500697 mIconPolicy = new PhoneStatusBarPolicy(mContext, mIconController, mCastController,
Jason Monk3e189872016-01-12 09:10:34 -0500698 mHotspotController, mUserInfoController, mBluetoothController,
Jason Monkf23aa992016-01-22 16:45:21 -0500699 mRotationLockController, mNetworkController.getDataSaverController());
John Spurlock604a5ee2015-06-01 12:27:22 -0400700 mIconPolicy.setCurrentUserSetup(mUserSetup);
John Spurlocke677d712014-02-13 12:52:19 -0500701 mSettingsObserver.onChange(false); // set up
Chris Wrenf6e83f42013-09-11 14:02:59 -0400702
703 mHeadsUpObserver.onChange(true); // set up
704 if (ENABLE_HEADS_UP) {
705 mContext.getContentResolver().registerContentObserver(
Chris Wren10d82df2014-03-01 10:34:51 -0500706 Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED), true,
Chris Wrenf6e83f42013-09-11 14:02:59 -0400707 mHeadsUpObserver);
Chris Wren22ae46e2014-02-26 18:08:09 -0500708 mContext.getContentResolver().registerContentObserver(
709 Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
710 mHeadsUpObserver);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400711 }
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200712 mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
Christoph Studer2231c6e2014-12-19 12:40:13 +0100713 mUnlockMethodCache.addListener(this);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100714 startKeyguard();
John Spurlockbf370992014-06-17 13:58:31 -0400715
Selim Cinek99415392016-09-09 14:58:41 -0700716 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateCallback);
John Spurlockbf370992014-06-17 13:58:31 -0400717 mDozeServiceHost = new DozeServiceHost();
Jeff Brown4d69e222014-09-18 15:27:50 -0700718 putComponent(DozeHost.class, mDozeServiceHost);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200719 putComponent(PhoneStatusBar.class, this);
John Spurlock89f060a2014-07-16 21:03:15 -0400720
721 setControllerUsers();
Chris Wrencd8f4f72014-08-27 18:48:13 -0400722
723 notifyUserAboutHiddenNotifications();
Jason Monk18f99d92014-09-11 13:36:42 -0400724
725 mScreenPinningRequest = new ScreenPinningRequest(mContext);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700726 mFalsingManager = FalsingManager.getInstance(mContext);
Joe Onorato808182d2010-07-09 18:52:06 -0400727 }
728
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700729 protected void createIconController() {
730 mIconController = new StatusBarIconController(
731 mContext, mStatusBarView, mKeyguardStatusBar, this);
732 }
733
Joe Onorato808182d2010-07-09 18:52:06 -0400734 // ================================================================================
735 // Constructing the view
736 // ================================================================================
Jim Millere898ac52012-04-06 17:10:57 -0700737 protected PhoneStatusBarView makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400738 final Context context = mContext;
Joe Onorato808182d2010-07-09 18:52:06 -0400739
Daniel Sandler6e8db882011-10-26 15:40:51 -0400740 updateDisplaySize(); // populates mDisplayMetrics
Jorim Jaggi2e115c52014-07-01 21:27:58 +0200741 updateResources();
Joe Onorato808182d2010-07-09 18:52:06 -0400742
Xiaohui Chend839d1a2016-01-21 13:05:02 -0800743 inflateStatusBarWindow(context);
Selim Cinek4e6b2d32015-06-25 20:15:33 -0400744 mStatusBarWindow.setService(this);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400745 mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
746 @Override
747 public boolean onTouch(View v, MotionEvent event) {
John Spurlock9deaa282013-07-25 13:03:47 -0400748 checkUserAutohide(v, event);
Adrian Roos6d53de62016-12-19 16:17:50 -0800749 checkRemoteInputOutside(event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400750 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandler37a38aa2013-02-13 17:15:57 -0500751 if (mExpandedVisible) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400752 animateCollapsePanels();
Daniel Sandler21b274e2012-05-02 15:07:51 -0400753 }
754 }
Chris Wren5de6e942012-05-16 14:22:21 -0400755 return mStatusBarWindow.onTouchEvent(event);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700756 }
757 });
Daniel Sandler21b274e2012-05-02 15:07:51 -0400758
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100759 mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
760 R.id.notification_panel);
Daniel Sandler040c2e42012-10-17 00:56:33 -0400761 mNotificationPanel.setStatusBar(this);
Selim Cinek53f8e7d2016-03-25 02:28:01 -0700762 mNotificationPanel.setGroupManager(mGroupManager);
Joe Onorato808182d2010-07-09 18:52:06 -0400763
Xiaohui Chen9f967112016-01-07 14:14:06 -0800764 mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
765 mStatusBarView.setBar(this);
766 mStatusBarView.setPanel(mNotificationPanel);
767
Jeff Brown98365d72012-08-19 20:30:52 -0700768 if (!ActivityManager.isHighEndGfx()) {
Romain Guy328b3582012-05-08 15:30:57 -0700769 mStatusBarWindow.setBackground(null);
Alan Viverette4a357cd2015-03-18 18:37:18 -0700770 mNotificationPanel.setBackground(new FastColorDrawable(context.getColor(
Romain Guy648342f2012-05-25 10:44:45 -0700771 R.color.notification_panel_solid_background)));
Romain Guy328b3582012-05-08 15:30:57 -0700772 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700773
Selim Cinek83bc7832015-10-22 13:26:54 -0700774 mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow, mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700775 mHeadsUpManager.setBar(this);
776 mHeadsUpManager.addListener(this);
777 mHeadsUpManager.addListener(mNotificationPanel);
Selim Cinekef5127e2015-12-21 16:55:58 -0800778 mHeadsUpManager.addListener(mGroupManager);
Selim Cinekadd95262016-12-06 14:34:47 -0800779 mHeadsUpManager.addListener(mVisualStabilityManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700780 mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
Selim Cinekfbe9a442015-04-13 16:09:49 -0700781 mNotificationData.setHeadsUpManager(mHeadsUpManager);
Selim Cinek967ed2a2016-04-08 18:29:11 -0700782 mGroupManager.setHeadsUpManager(mHeadsUpManager);
Selim Cinekadd95262016-12-06 14:34:47 -0800783 mHeadsUpManager.setVisualStabilityManager(mVisualStabilityManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700784
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400785 if (MULTIUSER_DEBUG) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100786 mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
787 R.id.header_debug_info);
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400788 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
789 }
Joe Onorato808182d2010-07-09 18:52:06 -0400790
Daniel Sandler0129b312011-05-11 11:54:11 -0400791 try {
Jeff Brown98365d72012-08-19 20:30:52 -0700792 boolean showNav = mWindowManagerService.hasNavigationBar();
John Spurlockcd686b52013-06-05 10:13:46 -0400793 if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
Daniel Sandler0129b312011-05-11 11:54:11 -0400794 if (showNav) {
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800795 createNavigationBarView(context);
Daniel Sandler0129b312011-05-11 11:54:11 -0400796 }
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400797 } catch (RemoteException ex) {
798 // no window manager? good luck with that
Daniel Sandler0129b312011-05-11 11:54:11 -0400799 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400800
Annie Chin937a9912016-05-31 10:14:23 -0700801 mAssistManager = SystemUIFactory.getInstance().createAssistManager(this, context);
Selim Cineke70d6532015-04-24 16:46:13 -0700802
Joe Onorato808182d2010-07-09 18:52:06 -0400803 // figure out which pixel-format to use for the status bar.
Daniel Sandlerf733c2a2011-09-25 15:03:40 -0400804 mPixelFormat = PixelFormat.OPAQUE;
Daniel Sandler173bae22012-09-25 14:37:42 -0400805
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100806 mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
807 R.id.notification_stack_scroller);
808 mStackScroller.setLongPressListener(getNotificationLongClicker());
Selim Cinek19c8c702014-08-25 22:09:19 +0200809 mStackScroller.setPhoneStatusBar(this);
Selim Cinekb5605e52015-02-20 18:21:41 +0100810 mStackScroller.setGroupManager(mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700811 mStackScroller.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb5605e52015-02-20 18:21:41 +0100812 mGroupManager.setOnGroupChangeListener(mStackScroller);
Selim Cinekadd95262016-12-06 14:34:47 -0800813 mVisualStabilityManager.setVisibilityLocationProvider(mStackScroller);
Selim Cinek80a14e52014-03-27 16:58:04 +0100814
Selim Cinek3e7592d2016-04-11 09:35:54 +0800815 inflateOverflowContainer();
Selim Cinek01af3342016-02-09 19:25:31 -0800816 inflateEmptyShadeView();
817 inflateDismissView();
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100818 mExpandedContents = mStackScroller;
Selim Cinek67b22602014-03-10 15:40:16 +0100819
Selim Cineka0fad3b2014-09-19 17:20:05 +0200820 mBackdrop = (BackDropView) mStatusBarWindow.findViewById(R.id.backdrop);
821 mBackdropFront = (ImageView) mBackdrop.findViewById(R.id.backdrop_front);
822 mBackdropBack = (ImageView) mBackdrop.findViewById(R.id.backdrop_back);
823
Jorim Jaggie31f6b82016-07-01 16:15:09 -0700824 if (ENABLE_LOCKSCREEN_WALLPAPER) {
825 mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
826 }
827
Selim Cineka0fad3b2014-09-19 17:20:05 +0200828 ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
829 ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
Selim Cinekaac93252015-04-14 20:04:12 -0700830 View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
Xiaohui Chen5da71352016-02-22 10:04:41 -0800831 mScrimController = SystemUIFactory.getInstance().createScrimController(
Jorim Jaggie31f6b82016-07-01 16:15:09 -0700832 scrimBehind, scrimInFront, headsUpScrim, mLockscreenWallpaper);
Selim Cinek25503252016-03-03 15:31:43 -0800833 if (mScrimSrcModeEnabled) {
834 Runnable runnable = new Runnable() {
835 @Override
836 public void run() {
837 boolean asSrc = mBackdrop.getVisibility() != View.VISIBLE;
838 mScrimController.setDrawBehindAsSrc(asSrc);
839 mStackScroller.setDrawBackgroundAsSrc(asSrc);
840 }
841 };
842 mBackdrop.setOnVisibilityChangedRunnable(runnable);
843 runnable.run();
844 }
Selim Cinekaac93252015-04-14 20:04:12 -0700845 mHeadsUpManager.addListener(mScrimController);
846 mStackScroller.setScrimController(mScrimController);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200847 mStatusBarView.setScrimController(mScrimController);
Jorim Jaggi048af1f2014-11-11 22:51:10 +0100848 mDozeScrimController = new DozeScrimController(mScrimController, context);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200849
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200850 mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200851 mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200852 mKeyguardBottomArea =
853 (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
854 mKeyguardBottomArea.setActivityStarter(this);
Selim Cineke70d6532015-04-24 16:46:13 -0700855 mKeyguardBottomArea.setAssistManager(mAssistManager);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200856 mKeyguardIndicationController = new KeyguardIndicationController(mContext,
857 (KeyguardIndicationTextView) mStatusBarWindow.findViewById(
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700858 R.id.keyguard_indication_text),
859 mKeyguardBottomArea.getLockIcon());
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200860 mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400861
Xiaohui Chenf43491f2016-02-01 12:19:35 -0800862 // set the initial view visibility
Joe Onorato808182d2010-07-09 18:52:06 -0400863 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400864
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700865 createIconController();
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100866
Jason Monk4ae97d32014-12-17 10:14:33 -0500867 // Background thread for any controllers that need it.
868 mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
869 mHandlerThread.start();
870
Daniel Sandler2b697352011-07-22 16:23:09 -0400871 // Other icons
Jason Monk05b86bc2015-05-19 14:21:28 -0400872 mLocationController = new LocationControllerImpl(mContext,
873 mHandlerThread.getLooper()); // will post a notification
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700874 mBatteryController = createBatteryController();
John Spurlock0ff62e02014-07-22 16:15:08 -0400875 mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
876 @Override
Jason Monkc06fbb12016-01-08 14:12:18 -0500877 public void onPowerSaveChanged(boolean isPowerSave) {
John Spurlock0ff62e02014-07-22 16:15:08 -0400878 mHandler.post(mCheckBarModes);
John Spurlockd96179e2014-08-21 16:43:45 -0400879 if (mDozeServiceHost != null) {
Jason Monkc06fbb12016-01-08 14:12:18 -0500880 mDozeServiceHost.firePowerSaveChanged(isPowerSave);
John Spurlockd96179e2014-08-21 16:43:45 -0400881 }
John Spurlock0ff62e02014-07-22 16:15:08 -0400882 }
883 @Override
884 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
885 // noop
886 }
887 });
Jason Monk30d80042015-05-08 16:54:18 -0400888 mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monkfd57ea72016-04-29 13:37:58 -0400889 mNetworkController.setUserSetupComplete(mUserSetup);
Jason Monk51e4dc02014-07-22 12:00:47 -0400890 mHotspotController = new HotspotControllerImpl(mContext);
Jason Monk4ae97d32014-12-17 10:14:33 -0500891 mBluetoothController = new BluetoothControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monk3d5f5512014-07-25 11:17:28 -0400892 mSecurityController = new SecurityControllerImpl(mContext);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400893 if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) {
894 mRotationLockController = new RotationLockControllerImpl(mContext);
John Spurlock8ab172e2013-12-19 16:39:23 -0500895 }
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200896 mUserInfoController = new UserInfoController(mContext);
John Spurlock86005342014-05-23 11:58:00 -0400897 mVolumeComponent = getComponent(VolumeComponent.class);
John Spurlockf2565a82014-10-23 20:16:22 -0400898 if (mVolumeComponent != null) {
899 mZenModeController = mVolumeComponent.getZenController();
900 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400901 mCastController = new CastControllerImpl(mContext);
Xiaohui Chen10942302015-12-16 16:38:13 -0800902
903 initSignalCluster(mStatusBarView);
904 initSignalCluster(mKeyguardStatusBar);
Adrian Roos316bf542016-08-23 17:53:07 +0200905 initEmergencyCryptkeeperText();
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400906
Adrian Roosb83777b2014-06-30 15:11:53 +0200907 mFlashlightController = new FlashlightController(mContext);
Adrian Roos1e1d6ac2014-07-22 17:18:55 +0200908 mKeyguardBottomArea.setFlashlightController(mFlashlightController);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200909 mKeyguardBottomArea.setPhoneStatusBar(this);
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700910 mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200911 mAccessibilityController = new AccessibilityController(mContext);
912 mKeyguardBottomArea.setAccessibilityController(mAccessibilityController);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200913 mNextAlarmController = new NextAlarmController(mContext);
Jorim Jaggi86905582016-02-09 21:36:09 -0800914 mLightStatusBarController = new LightStatusBarController(mIconController,
915 mBatteryController);
Jason Monk8a3a9642015-06-05 11:01:30 -0400916 mKeyguardMonitor = new KeyguardMonitor(mContext);
Amith Yamasani69476362016-07-13 11:59:16 -0700917 mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
918 mHandler, this);
Fyodor Kupolovcd86ebf2015-09-29 17:06:50 -0700919 if (UserManager.get(mContext).isUserSwitcherEnabled()) {
Rakesh Iyer2790a372016-01-22 15:33:39 -0800920 createUserSwitcher();
Adrian Roos2b154a92014-11-17 15:18:39 +0100921 }
Adrian Roos723632e2014-07-23 21:13:21 +0200922
John Spurlockaf8d6c42014-05-07 17:49:08 -0400923 // Set up the quick settings tile panel
Clara Bayarri9b1fdff2016-04-21 14:28:47 +0100924 AutoReinflateContainer container = (AutoReinflateContainer) mStatusBarWindow.findViewById(
925 R.id.qs_auto_reinflate_container);
Jason Monk46dbfb42016-02-25 14:59:20 -0500926 if (container != null) {
Xiaohui Chen311b98e2016-03-30 11:55:54 -0700927 final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,
John Spurlockaf8d6c42014-05-07 17:49:08 -0400928 mBluetoothController, mLocationController, mRotationLockController,
Jason Monk51e4dc02014-07-22 12:00:47 -0400929 mNetworkController, mZenModeController, mHotspotController,
John Spurlock657c62c2014-07-22 12:18:09 -0400930 mCastController, mFlashlightController,
Jason Monkabe19742015-09-29 09:47:06 -0400931 mUserSwitcherController, mUserInfoController, mKeyguardMonitor,
Jason Monk46dbfb42016-02-25 14:59:20 -0500932 mSecurityController, mBatteryController, mIconController,
933 mNextAlarmController);
Adrian Roos5fd872e2014-08-12 17:28:58 +0200934 mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
Jason Monk46dbfb42016-02-25 14:59:20 -0500935 container.addInflateListener(new InflateListener() {
John Spurlockbceed062014-08-10 18:04:16 -0400936 @Override
Jason Monk46dbfb42016-02-25 14:59:20 -0500937 public void onInflated(View v) {
938 QSContainer qsContainer = (QSContainer) v.findViewById(
939 R.id.quick_settings_container);
940 qsContainer.setHost(qsh);
941 mQSPanel = qsContainer.getQsPanel();
942 mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
Kaori Katouccf08d72015-05-26 16:25:04 +0900943 mKeyguardStatusBar.setQSPanel(mQSPanel);
Jason Monk46dbfb42016-02-25 14:59:20 -0500944 mHeader = qsContainer.getHeader();
945 initSignalCluster(mHeader);
946 mHeader.setActivityStarter(PhoneStatusBar.this);
John Spurlockbceed062014-08-10 18:04:16 -0400947 }
948 });
Siva Velusamy537421b2012-09-14 14:45:02 -0700949 }
950
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200951 // User info. Trigger first load.
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200952 mKeyguardStatusBar.setUserInfoController(mUserInfoController);
Adrian Roosffc90972015-06-09 18:09:49 -0700953 mKeyguardStatusBar.setUserSwitcherController(mUserSwitcherController);
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200954 mUserInfoController.reloadUserInfo();
955
Jorim Jaggi708f7722014-08-20 17:30:38 +0200956 ((BatteryMeterView) mStatusBarView.findViewById(R.id.battery)).setBatteryController(
957 mBatteryController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200958 mKeyguardStatusBar.setBatteryController(mBatteryController);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200959
Adrian Roos7bb38a92016-07-21 11:44:01 -0700960 mReportRejectedTouch = mStatusBarWindow.findViewById(R.id.report_rejected_touch);
961 if (mReportRejectedTouch != null) {
962 updateReportRejectedTouchVisibility();
963 mReportRejectedTouch.setOnClickListener(v -> {
964 Uri session = mFalsingManager.reportRejectedTouch();
965 if (session == null) { return; }
966
967 StringWriter message = new StringWriter();
968 message.write("Build info: ");
969 message.write(SystemProperties.get("ro.build.description"));
970 message.write("\nSerial number: ");
971 message.write(SystemProperties.get("ro.serialno"));
972 message.write("\n");
973
974 PrintWriter falsingPw = new PrintWriter(message);
975 FalsingLog.dump(falsingPw);
976 falsingPw.flush();
977
978 startActivityDismissingKeyguard(Intent.createChooser(new Intent(Intent.ACTION_SEND)
979 .setType("*/*")
980 .putExtra(Intent.EXTRA_SUBJECT, "Rejected touch report")
981 .putExtra(Intent.EXTRA_STREAM, session)
982 .putExtra(Intent.EXTRA_TEXT, message.toString()),
983 "Share rejected touch report")
984 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
985 true /* onlyProvisioned */, true /* dismissShade */);
986 });
987 }
988
989
John Spurlock56d007b2013-10-28 18:40:56 -0400990 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
991 mBroadcastReceiver.onReceive(mContext,
992 new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
Selim Cinek372d1bd2015-08-14 13:19:37 -0700993 mGestureWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
994 "GestureWakeLock");
Selim Cinek69ff8af2015-08-25 19:03:48 -0700995 mVibrator = mContext.getSystemService(Vibrator.class);
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700996
Joe Onorato808182d2010-07-09 18:52:06 -0400997 // receive broadcasts
998 IntentFilter filter = new IntentFilter();
Joe Onorato808182d2010-07-09 18:52:06 -0400999 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
1000 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -04001001 filter.addAction(Intent.ACTION_SCREEN_ON);
phweiss923d2cc2016-12-14 21:37:48 +01001002 filter.addAction(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
Kenny Guy44fc65f2014-11-28 22:18:14 +00001003 context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
Joe Onorato808182d2010-07-09 18:52:06 -04001004
Adrian Roos8e3e8362015-07-16 19:42:22 -07001005 IntentFilter demoFilter = new IntentFilter();
1006 if (DEBUG_MEDIA_FAKE_ARTWORK) {
1007 demoFilter.addAction(ACTION_FAKE_ARTWORK);
1008 }
1009 demoFilter.addAction(ACTION_DEMO);
1010 context.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
1011 android.Manifest.permission.DUMP, null);
1012
John Spurlock919adac2012-10-02 16:41:12 -04001013 // listen for USER_SETUP_COMPLETE setting (per-user)
1014 resetUserSetupObserver();
1015
Chris Craik2507c342015-05-04 14:36:49 -07001016 // disable profiling bars, since they overlap and clutter the output on app windows
1017 ThreadedRenderer.overrideProperty("disableProfileBars", "true");
1018
1019 // Private API call to make the shadows look better for Recents
1020 ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
1021
Daniel Sandlera310af82012-04-24 01:20:13 -04001022 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -04001023 }
1024
Adrian Roos316bf542016-08-23 17:53:07 +02001025 private void initEmergencyCryptkeeperText() {
1026 View emergencyViewStub = mStatusBarWindow.findViewById(R.id.emergency_cryptkeeper_text);
1027 if (mNetworkController.hasEmergencyCryptKeeperText()) {
1028 if (emergencyViewStub != null) {
1029 ((ViewStub) emergencyViewStub).inflate();
1030 }
1031 mNetworkController.addSignalCallback(new NetworkController.SignalCallback() {
1032 @Override
1033 public void setIsAirplaneMode(NetworkController.IconState icon) {
1034 recomputeDisableFlags(true /* animate */);
1035 }
1036 });
1037 } else if (emergencyViewStub != null) {
1038 ViewGroup parent = (ViewGroup) emergencyViewStub.getParent();
1039 parent.removeView(emergencyViewStub);
1040 }
1041 }
1042
Anthony Chenda62fdcd52016-04-06 16:15:14 -07001043 protected BatteryController createBatteryController() {
1044 return new BatteryControllerImpl(mContext);
1045 }
1046
Selim Cinek3e7592d2016-04-11 09:35:54 +08001047 private void inflateOverflowContainer() {
1048 mKeyguardIconOverflowContainer =
1049 (NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
1050 R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
1051 mKeyguardIconOverflowContainer.setOnActivatedListener(this);
1052 mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
1053 mStackScroller.setOverflowContainer(mKeyguardIconOverflowContainer);
1054 }
1055
Selim Cinek01af3342016-02-09 19:25:31 -08001056 @Override
Selim Cinek3e7592d2016-04-11 09:35:54 +08001057 protected void onDensityOrFontScaleChanged() {
1058 super.onDensityOrFontScaleChanged();
1059 mScrimController.onDensityOrFontScaleChanged();
1060 mStatusBarView.onDensityOrFontScaleChanged();
Adrian Roosd390b892016-05-05 10:50:49 -04001061 if (mBrightnessMirrorController != null) {
1062 mBrightnessMirrorController.onDensityOrFontScaleChanged();
1063 }
Selim Cinek3e7592d2016-04-11 09:35:54 +08001064 inflateSignalClusters();
1065 mIconController.onDensityOrFontScaleChanged();
Selim Cinek01af3342016-02-09 19:25:31 -08001066 inflateDismissView();
1067 updateClearAll();
1068 inflateEmptyShadeView();
1069 updateEmptyShadeView();
Selim Cinek3e7592d2016-04-11 09:35:54 +08001070 inflateOverflowContainer();
Selim Cinekaa8bbf12016-05-04 14:13:20 -07001071 mStatusBarKeyguardViewManager.onDensityOrFontScaleChanged();
Adrian Roosd390b892016-05-05 10:50:49 -04001072 mUserInfoController.onDensityOrFontScaleChanged();
1073 if (mUserSwitcherController != null) {
1074 mUserSwitcherController.onDensityOrFontScaleChanged();
1075 }
1076 if (mKeyguardUserSwitcher != null) {
1077 mKeyguardUserSwitcher.onDensityOrFontScaleChanged();
1078 }
Selim Cinek3e7592d2016-04-11 09:35:54 +08001079 }
1080
1081 private void inflateSignalClusters() {
1082 SignalClusterView signalClusterView = reinflateSignalCluster(mStatusBarView);
1083 mIconController.setSignalCluster(signalClusterView);
Selim Cinek6ebba592016-05-31 15:28:28 -07001084 reinflateSignalCluster(mKeyguardStatusBar);
Selim Cinek3e7592d2016-04-11 09:35:54 +08001085 }
1086
1087 private SignalClusterView reinflateSignalCluster(View view) {
1088 SignalClusterView signalCluster =
1089 (SignalClusterView) view.findViewById(R.id.signal_cluster);
1090 if (signalCluster != null) {
1091 ViewParent parent = signalCluster.getParent();
1092 if (parent instanceof ViewGroup) {
1093 ViewGroup viewParent = (ViewGroup) parent;
1094 int index = viewParent.indexOfChild(signalCluster);
1095 viewParent.removeView(signalCluster);
1096 SignalClusterView newCluster = (SignalClusterView) LayoutInflater.from(mContext)
1097 .inflate(R.layout.signal_cluster_view, viewParent, false);
1098 ViewGroup.MarginLayoutParams layoutParams =
1099 (ViewGroup.MarginLayoutParams) viewParent.getLayoutParams();
1100 layoutParams.setMarginsRelative(
1101 mContext.getResources().getDimensionPixelSize(
1102 R.dimen.signal_cluster_margin_start),
1103 0, 0, 0);
1104 newCluster.setLayoutParams(layoutParams);
1105 newCluster.setSecurityController(mSecurityController);
1106 newCluster.setNetworkController(mNetworkController);
1107 viewParent.addView(newCluster, index);
1108 return newCluster;
1109 }
1110 return signalCluster;
1111 }
1112 return null;
Selim Cinek01af3342016-02-09 19:25:31 -08001113 }
1114
1115 private void inflateEmptyShadeView() {
1116 mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
1117 R.layout.status_bar_no_notifications, mStackScroller, false);
1118 mStackScroller.setEmptyShadeView(mEmptyShadeView);
1119 }
1120
1121 private void inflateDismissView() {
1122 mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
1123 R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
1124 mDismissView.setOnButtonClickListener(new View.OnClickListener() {
1125 @Override
1126 public void onClick(View v) {
1127 MetricsLogger.action(mContext, MetricsEvent.ACTION_DISMISS_ALL_NOTES);
1128 clearAllNotifications();
1129 }
1130 });
1131 mStackScroller.setDismissView(mDismissView);
1132 }
1133
Rakesh Iyer2790a372016-01-22 15:33:39 -08001134 protected void createUserSwitcher() {
1135 mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
1136 (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
1137 mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
1138 }
1139
Xiaohui Chend839d1a2016-01-21 13:05:02 -08001140 protected void inflateStatusBarWindow(Context context) {
1141 mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
1142 R.layout.super_status_bar, null);
1143 }
1144
Rakesh Iyer1186faa2015-12-07 16:48:46 -08001145 protected void createNavigationBarView(Context context) {
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -08001146 inflateNavigationBarView(context);
Rakesh Iyer1186faa2015-12-07 16:48:46 -08001147 mNavigationBarView.setDisabledFlags(mDisabled1);
1148 mNavigationBarView.setComponents(mRecents, getComponent(Divider.class));
1149 mNavigationBarView.setOnVerticalChangedListener(
1150 new NavigationBarView.OnVerticalChangedListener() {
1151 @Override
1152 public void onVerticalChanged(boolean isVertical) {
1153 if (mAssistManager != null) {
1154 mAssistManager.onConfigurationChanged();
1155 }
1156 mNotificationPanel.setQsScrimEnabled(!isVertical);
1157 }
1158 });
1159 mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
1160 @Override
1161 public boolean onTouch(View v, MotionEvent event) {
1162 checkUserAutohide(v, event);
1163 return false;
1164 }});
1165 }
1166
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -08001167 protected void inflateNavigationBarView(Context context) {
Jason Monk4f878ef2016-01-23 14:37:38 -05001168 mNavigationBarView = (NavigationBarView) View.inflate(
1169 context, R.layout.navigation_bar, null);
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -08001170 }
1171
1172 protected void initSignalCluster(View containerView) {
Xiaohui Chen10942302015-12-16 16:38:13 -08001173 SignalClusterView signalCluster =
1174 (SignalClusterView) containerView.findViewById(R.id.signal_cluster);
1175 if (signalCluster != null) {
Xiaohui Chen10942302015-12-16 16:38:13 -08001176 signalCluster.setSecurityController(mSecurityController);
1177 signalCluster.setNetworkController(mNetworkController);
1178 }
1179 }
1180
Muyuan Lic510b5e2016-03-09 17:15:05 -08001181 public void clearAllNotifications() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001182
1183 // animate-swipe all dismissable notifications, then animate the shade closed
1184 int numChildren = mStackScroller.getChildCount();
1185
1186 final ArrayList<View> viewsToHide = new ArrayList<View>(numChildren);
1187 for (int i = 0; i < numChildren; i++) {
1188 final View child = mStackScroller.getChildAt(i);
Selim Cinekb5605e52015-02-20 18:21:41 +01001189 if (child instanceof ExpandableNotificationRow) {
1190 if (mStackScroller.canChildBeDismissed(child)) {
1191 if (child.getVisibility() == View.VISIBLE) {
1192 viewsToHide.add(child);
1193 }
1194 }
1195 ExpandableNotificationRow row = (ExpandableNotificationRow) child;
1196 List<ExpandableNotificationRow> children = row.getNotificationChildren();
1197 if (row.areChildrenExpanded() && children != null) {
1198 for (ExpandableNotificationRow childRow : children) {
Selim Cinek1d359792017-01-13 14:43:43 -08001199 if (mStackScroller.canChildBeDismissed(childRow)) {
1200 if (childRow.getVisibility() == View.VISIBLE) {
1201 viewsToHide.add(childRow);
1202 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001203 }
1204 }
Dan Sandlereceda3d2014-07-21 15:35:01 -04001205 }
1206 }
1207 }
1208 if (viewsToHide.isEmpty()) {
1209 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
1210 return;
1211 }
1212
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001213 addPostCollapseAction(new Runnable() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001214 @Override
1215 public void run() {
Selim Cinek9c17b772015-07-07 20:37:09 -07001216 mStackScroller.setDismissAllInProgress(false);
Dan Sandlereceda3d2014-07-21 15:35:01 -04001217 try {
1218 mBarService.onClearAllNotifications(mCurrentUserId);
1219 } catch (Exception ex) { }
1220 }
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001221 });
Dan Sandlereceda3d2014-07-21 15:35:01 -04001222
1223 performDismissAllAnimations(viewsToHide);
1224
1225 }
1226
1227 private void performDismissAllAnimations(ArrayList<View> hideAnimatedList) {
1228 Runnable animationFinishAction = new Runnable() {
1229 @Override
1230 public void run() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001231 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
1232 }
1233 };
1234
1235 // let's disable our normal animations
1236 mStackScroller.setDismissAllInProgress(true);
1237
1238 // Decrease the delay for every row we animate to give the sense of
1239 // accelerating the swipes
1240 int rowDelayDecrement = 10;
1241 int currentDelay = 140;
Selim Cinek7d5f3742014-11-07 18:07:49 +01001242 int totalDelay = 180;
Dan Sandlereceda3d2014-07-21 15:35:01 -04001243 int numItems = hideAnimatedList.size();
Selim Cinek7d5f3742014-11-07 18:07:49 +01001244 for (int i = numItems - 1; i >= 0; i--) {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001245 View view = hideAnimatedList.get(i);
1246 Runnable endRunnable = null;
Selim Cinek7d5f3742014-11-07 18:07:49 +01001247 if (i == 0) {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001248 endRunnable = animationFinishAction;
1249 }
1250 mStackScroller.dismissViewAnimated(view, endRunnable, totalDelay, 260);
1251 currentDelay = Math.max(50, currentDelay - rowDelayDecrement);
1252 totalDelay += currentDelay;
1253 }
1254 }
1255
John Spurlockae641c92014-06-30 18:11:40 -04001256 @Override
1257 protected void setZenMode(int mode) {
1258 super.setZenMode(mode);
1259 if (mIconPolicy != null) {
1260 mIconPolicy.setZenMode(mode);
1261 }
1262 }
1263
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001264 protected void startKeyguard() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001265 Trace.beginSection("PhoneStatusBar#startKeyguard");
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001266 KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001267 mFingerprintUnlockController = new FingerprintUnlockController(mContext,
1268 mStatusBarWindowManager, mDozeScrimController, keyguardViewMediator,
1269 mScrimController, this);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001270 mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001271 getBouncerContainer(), mStatusBarWindowManager, mScrimController,
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001272 mFingerprintUnlockController);
Selim Cinekcfafe4e2015-08-11 14:58:44 -07001273 mKeyguardIndicationController.setStatusBarKeyguardViewManager(
1274 mStatusBarKeyguardViewManager);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001275 mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
Nicolas Prevot1dbbe7d2016-05-17 12:52:54 +01001276 mIconPolicy.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
Adrian Roosd28ccd72016-01-06 15:23:14 +01001277 mRemoteInputController.addCallback(mStatusBarKeyguardViewManager);
Adrian Roosc0a579e2016-03-30 16:43:58 -07001278
Adrian Roos18d099a2016-05-19 15:28:18 -07001279 mRemoteInputController.addCallback(new RemoteInputController.Callback() {
1280 @Override
1281 public void onRemoteInputSent(Entry entry) {
1282 if (FORCE_REMOTE_INPUT_HISTORY && mKeysKeptForRemoteInput.contains(entry.key)) {
1283 removeNotification(entry.key, null);
1284 } else if (mRemoteInputEntriesToRemoveOnCollapse.contains(entry)) {
1285 // We're currently holding onto this notification, but from the apps point of
1286 // view it is already canceled, so we'll need to cancel it on the apps behalf
1287 // after sending - unless the app posts an update in the mean time, so wait a
1288 // bit.
1289 mHandler.postDelayed(() -> {
1290 if (mRemoteInputEntriesToRemoveOnCollapse.remove(entry)) {
1291 removeNotification(entry.key, null);
1292 }
1293 }, REMOTE_INPUT_KEPT_ENTRY_AUTO_CANCEL_DELAY);
Adrian Roosc0a579e2016-03-30 16:43:58 -07001294 }
Adrian Roos18d099a2016-05-19 15:28:18 -07001295 }
1296 });
Adrian Roosc0a579e2016-03-30 16:43:58 -07001297
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001298 mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
Jorim Jaggi86905582016-02-09 21:36:09 -08001299 mLightStatusBarController.setFingerprintUnlockController(mFingerprintUnlockController);
Nick Desaulniers1d396752016-07-25 15:05:33 -07001300 Trace.endSection();
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001301 }
1302
Michael Jurka7f2668c2012-03-27 07:49:52 -07001303 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -07001304 protected View getStatusBarView() {
1305 return mStatusBarView;
1306 }
1307
Jorim Jaggi0a27be82014-06-11 03:22:39 +02001308 public StatusBarWindowView getStatusBarWindow() {
1309 return mStatusBarWindow;
1310 }
1311
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001312 protected ViewGroup getBouncerContainer() {
1313 return mStatusBarWindow;
1314 }
1315
Joe Onoratodc100302011-01-11 17:07:41 -08001316 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -04001317 if (mNaturalBarHeight < 0) {
1318 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -07001319 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -04001320 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
1321 }
1322 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -08001323 }
1324
Daniel Sandler5c8da942011-06-28 00:29:04 -04001325 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
Jim Miller07e03842016-06-22 15:18:13 -07001326 @Override
Daniel Sandler5c8da942011-06-28 00:29:04 -04001327 public void onClick(View v) {
John Spurlockc8b46ca2013-04-08 12:59:26 -04001328 awakenDreams();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001329 toggleRecentApps();
1330 }
1331 };
Chris Wren0c8275b2012-05-08 13:36:48 -04001332
Phil Weaver315c34e2016-02-19 15:12:29 -08001333 @Override
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001334 protected void toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction) {
Phil Weaver315c34e2016-02-19 15:12:29 -08001335 if (mRecents == null) {
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001336 return;
Phil Weaver315c34e2016-02-19 15:12:29 -08001337 }
1338 int dockSide = WindowManagerProxy.getInstance().getDockSide();
1339 if (dockSide == WindowManager.DOCKED_INVALID) {
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001340 mRecents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE,
1341 ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, null, metricsDockAction);
Phil Weaver315c34e2016-02-19 15:12:29 -08001342 } else {
1343 EventBus.getDefault().send(new UndockingTaskEvent());
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001344 if (metricsUndockAction != -1) {
1345 MetricsLogger.action(mContext, metricsUndockAction);
1346 }
Phil Weaver315c34e2016-02-19 15:12:29 -08001347 }
1348 }
1349
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001350 private final View.OnLongClickListener mLongPressHomeListener
1351 = new View.OnLongClickListener() {
1352 @Override
1353 public boolean onLongClick(View v) {
1354 if (shouldDisableNavbarGestures()) {
1355 return false;
1356 }
Chris Wrenf6e9228b2016-01-26 18:04:35 -05001357 MetricsLogger.action(mContext, MetricsEvent.ACTION_ASSIST_LONG_PRESS);
Jorim Jaggi165ce062015-07-06 16:18:11 -07001358 mAssistManager.startAssist(new Bundle() /* args */);
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001359 awakenDreams();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001360 if (mNavigationBarView != null) {
Xiyuan Xiaee7dd052015-05-15 09:46:27 -07001361 mNavigationBarView.abortCurrentGesture();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001362 }
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001363 return true;
Jim Miller9a720f52012-05-30 03:19:43 -07001364 }
1365 };
1366
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001367 private final View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
Selim Cinek64be7722016-07-22 13:28:16 -07001368 public boolean mBlockedThisTouch;
1369
Jim Miller07e03842016-06-22 15:18:13 -07001370 @Override
Jim Millere898ac52012-04-06 17:10:57 -07001371 public boolean onTouch(View v, MotionEvent event) {
Selim Cinek64be7722016-07-22 13:28:16 -07001372 if (mBlockedThisTouch && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
1373 return true;
1374 }
1375 // If an incoming call is ringing, HOME is totally disabled.
1376 // (The user is already on the InCallUI at this point,
1377 // and his ONLY options are to answer or reject the call.)
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001378 switch (event.getAction()) {
Selim Cinek64be7722016-07-22 13:28:16 -07001379 case MotionEvent.ACTION_DOWN:
1380 mBlockedThisTouch = false;
1381 TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
1382 if (telecomManager != null && telecomManager.isRinging()) {
1383 if (mStatusBarKeyguardViewManager.isShowing()) {
1384 Log.i(TAG, "Ignoring HOME; there's a ringing incoming call. " +
1385 "No heads up");
1386 mBlockedThisTouch = true;
1387 return true;
1388 }
1389 }
1390 break;
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001391 case MotionEvent.ACTION_UP:
1392 case MotionEvent.ACTION_CANCEL:
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001393 awakenDreams();
1394 break;
1395 }
1396 return false;
Jim Millere898ac52012-04-06 17:10:57 -07001397 }
1398 };
Daniel Sandler5c8da942011-06-28 00:29:04 -04001399
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001400 private void awakenDreams() {
1401 if (mDreamManager != null) {
1402 try {
1403 mDreamManager.awaken();
1404 } catch (RemoteException e) {
1405 // fine, stay asleep then
1406 }
1407 }
1408 }
1409
Michael Jurka412cba82011-10-17 09:05:00 -07001410 private void prepareNavigationBarView() {
1411 mNavigationBarView.reorient();
1412
Jason Monka2081822016-01-18 14:41:03 -05001413 ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton();
1414 recentsButton.setOnClickListener(mRecentsClickListener);
1415 recentsButton.setOnTouchListener(mRecentsPreloadOnTouchListener);
1416 recentsButton.setLongClickable(true);
Jorim Jaggi4e723e62016-12-14 11:02:39 -08001417 recentsButton.setOnLongClickListener(this::handleLongPressBackRecents);
Anthony Chenada13042016-01-19 16:57:20 -08001418
Jason Monka2081822016-01-18 14:41:03 -05001419 ButtonDispatcher backButton = mNavigationBarView.getBackButton();
1420 backButton.setLongClickable(true);
Jorim Jaggi4e723e62016-12-14 11:02:39 -08001421 backButton.setOnLongClickListener(this::handleLongPressBackRecents);
Anthony Chenada13042016-01-19 16:57:20 -08001422
Jason Monka2081822016-01-18 14:41:03 -05001423 ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
1424 homeButton.setOnTouchListener(mHomeActionListener);
1425 homeButton.setOnLongClickListener(mLongPressHomeListener);
Anthony Chenada13042016-01-19 16:57:20 -08001426
Selim Cineke70d6532015-04-24 16:46:13 -07001427 mAssistManager.onConfigurationChanged();
Michael Jurka412cba82011-10-17 09:05:00 -07001428 }
1429
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001430 // For small-screen devices (read: phones) that lack hardware navigation buttons
Rakesh Iyer1186faa2015-12-07 16:48:46 -08001431 protected void addNavigationBar() {
John Spurlockcd686b52013-06-05 10:13:46 -04001432 if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -04001433 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001434
Adrian Roosa98b32c2016-08-11 10:41:08 -07001435 try {
1436 WindowManagerGlobal.getWindowManagerService()
1437 .watchRotation(new IRotationWatcher.Stub() {
1438 @Override
1439 public void onRotationChanged(int rotation) throws RemoteException {
1440 // We need this to be scheduled as early as possible to beat the redrawing of
1441 // window in response to the orientation change.
1442 Message msg = Message.obtain(mHandler, () -> {
1443 if (mNavigationBarView != null
1444 && mNavigationBarView.needsReorient(rotation)) {
1445 repositionNavigationBar();
1446 }
1447 });
1448 msg.setAsynchronous(true);
1449 mHandler.sendMessageAtFrontOfQueue(msg);
1450 }
1451 });
1452 } catch (RemoteException e) {
1453 throw e.rethrowFromSystemServer();
1454 }
1455
Michael Jurka412cba82011-10-17 09:05:00 -07001456 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001457
Jeff Brown98365d72012-08-19 20:30:52 -07001458 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001459 }
1460
Victor Chanecdb8b02016-01-07 18:32:43 -08001461 protected void repositionNavigationBar() {
John Spurlock56d007b2013-10-28 18:40:56 -04001462 if (mNavigationBarView == null || !mNavigationBarView.isAttachedToWindow()) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001463
Michael Jurka412cba82011-10-17 09:05:00 -07001464 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001465
Jorim Jaggi90dfb892016-07-25 15:57:36 +02001466 mWindowManager.updateViewLayout(mNavigationBarView, mNavigationBarView.getLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001467 }
1468
John Spurlock1bbd49d2012-10-19 11:09:32 -04001469 private void notifyNavigationBarScreenOn(boolean screenOn) {
1470 if (mNavigationBarView == null) return;
1471 mNavigationBarView.notifyScreenOn(screenOn);
1472 }
1473
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001474 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001475 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -07001476 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001477 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
1478 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001479 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
1480 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -07001481 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -04001482 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jorim Jaggic59a23f2016-05-24 14:53:36 -07001483 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
1484 | WindowManager.LayoutParams.FLAG_SLIPPERY,
John Spurlockad3e6cb2013-04-30 08:47:43 -04001485 PixelFormat.TRANSLUCENT);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001486 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -07001487 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001488 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
1489 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001490
1491 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001492 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001493 return lp;
1494 }
1495
Jason Monk07473ce2016-01-05 14:59:19 -05001496 @Override
1497 public void setIcon(String slot, StatusBarIcon icon) {
1498 mIconController.setIcon(slot, icon);
Joe Onorato808182d2010-07-09 18:52:06 -04001499 }
1500
Jason Monk07473ce2016-01-05 14:59:19 -05001501 @Override
1502 public void removeIcon(String slot) {
1503 mIconController.removeIcon(slot);
Joe Onorato808182d2010-07-09 18:52:06 -04001504 }
1505
John Spurlockbf20eab2014-04-09 16:40:39 -04001506 public UserHandle getCurrentUserHandle() {
1507 return new UserHandle(mCurrentUserId);
1508 }
1509
Christoph Studer71f18fd2014-05-20 17:02:04 +02001510 @Override
Selim Cinek379ff8f2015-02-20 17:03:16 +01001511 public void addNotification(StatusBarNotification notification, RankingMap ranking,
1512 Entry oldEntry) {
Chris Wrenaaa58d12014-06-03 14:29:12 -04001513 if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
Chris Wrend4db6cb2013-08-07 16:05:23 -04001514
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001515 mNotificationData.updateRanking(ranking);
Selim Cinek8d490d42015-04-10 00:05:50 -07001516 Entry shadeEntry = createNotificationViews(notification);
Chris Wrena4ef6202014-06-09 18:07:30 -04001517 if (shadeEntry == null) {
1518 return;
1519 }
Adrian Roosf6967e062016-06-21 16:12:48 -07001520 boolean isHeadsUped = shouldPeek(shadeEntry);
Selim Cinek31d9ef72015-04-15 19:29:49 -07001521 if (isHeadsUped) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001522 mHeadsUpManager.showNotification(shadeEntry);
Amith Yamasanif47e51e2015-04-17 10:02:15 -07001523 // Mark as seen immediately
1524 setNotificationShown(notification);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001525 }
Chris Wrena4ef6202014-06-09 18:07:30 -04001526
Selim Cinek31d9ef72015-04-15 19:29:49 -07001527 if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
Julia Reynoldsd5607292016-02-05 15:25:58 -05001528 if (shouldSuppressFullScreenIntent(notification.getKey())) {
Julia Reynolds61721582016-01-05 08:35:25 -05001529 if (DEBUG) {
1530 Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + notification.getKey());
1531 }
Julia Reynoldsf0f629f2016-02-25 09:34:04 -05001532 } else if (mNotificationData.getImportance(notification.getKey())
1533 < NotificationListenerService.Ranking.IMPORTANCE_MAX) {
1534 if (DEBUG) {
1535 Log.d(TAG, "No Fullscreen intent: not important enough: "
1536 + notification.getKey());
1537 }
Julia Reynolds61721582016-01-05 08:35:25 -05001538 } else {
1539 // Stop screensaver if the notification has a full-screen intent.
1540 // (like an incoming phone call)
1541 awakenDreams();
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -04001542
Julia Reynolds61721582016-01-05 08:35:25 -05001543 // not immersive & a full-screen alert should be shown
1544 if (DEBUG)
1545 Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
1546 try {
1547 EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
1548 notification.getKey());
1549 notification.getNotification().fullScreenIntent.send();
1550 shadeEntry.notifyFullScreenIntentLaunched();
1551 MetricsLogger.count(mContext, "note_fullscreen", 1);
1552 } catch (PendingIntent.CanceledException e) {
1553 }
John Spurlockbf20eab2014-04-09 16:40:39 -04001554 }
Joe Onorato808182d2010-07-09 18:52:06 -04001555 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001556 addNotificationViews(shadeEntry, ranking);
Joe Onorato808182d2010-07-09 18:52:06 -04001557 // Recalculate the position of the sliding windows and the titles.
1558 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001559 }
1560
Julia Reynoldsd5607292016-02-05 15:25:58 -05001561 private boolean shouldSuppressFullScreenIntent(String key) {
Dan Sandlerdc34df52016-04-07 21:04:46 -04001562 if (isDeviceInVrMode()) {
1563 return true;
1564 }
1565
Julia Reynolds0971cb02016-01-26 17:00:22 -05001566 if (mPowerManager.isInteractive()) {
Julia Reynolds0971cb02016-01-26 17:00:22 -05001567 return mNotificationData.shouldSuppressScreenOn(key);
Julia Reynoldsd5607292016-02-05 15:25:58 -05001568 } else {
1569 return mNotificationData.shouldSuppressScreenOff(key);
Julia Reynolds0971cb02016-01-26 17:00:22 -05001570 }
1571 }
1572
Chris Wren51c75102013-07-16 20:49:17 -04001573 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001574 protected void updateNotificationRanking(RankingMap ranking) {
Chris Wren333a61c2014-05-28 16:40:57 -04001575 mNotificationData.updateRanking(ranking);
Chris Wren333a61c2014-05-28 16:40:57 -04001576 updateNotifications();
1577 }
1578
1579 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001580 public void removeNotification(String key, RankingMap ranking) {
Selim Cinek684a4422015-04-15 16:18:39 -07001581 boolean deferRemoval = false;
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001582 if (mHeadsUpManager.isHeadsUp(key)) {
Adrian Roosc721fcc52016-04-29 11:28:37 -07001583 // A cancel() in repsonse to a remote input shouldn't be delayed, as it makes the
1584 // sending look longer than it takes.
1585 boolean ignoreEarliestRemovalTime = mRemoteInputController.isSpinning(key)
1586 && !FORCE_REMOTE_INPUT_HISTORY;
1587 deferRemoval = !mHeadsUpManager.removeNotification(key, ignoreEarliestRemovalTime);
Chris Wrena4ef6202014-06-09 18:07:30 -04001588 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001589 if (key.equals(mMediaNotificationKey)) {
1590 clearCurrentMediaNotification();
Adrian Roos52738322016-01-29 08:49:21 -08001591 updateMediaMetaData(true, true);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001592 }
Adrian Roosc0a579e2016-03-30 16:43:58 -07001593 if (FORCE_REMOTE_INPUT_HISTORY && mRemoteInputController.isSpinning(key)) {
1594 Entry entry = mNotificationData.get(key);
1595 StatusBarNotification sbn = entry.notification;
1596
1597 Notification.Builder b = Notification.Builder
1598 .recoverBuilder(mContext, sbn.getNotification().clone());
1599 CharSequence[] oldHistory = sbn.getNotification().extras
1600 .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
1601 CharSequence[] newHistory;
1602 if (oldHistory == null) {
1603 newHistory = new CharSequence[1];
1604 } else {
1605 newHistory = new CharSequence[oldHistory.length + 1];
1606 for (int i = 0; i < oldHistory.length; i++) {
1607 newHistory[i + 1] = oldHistory[i];
1608 }
1609 }
1610 newHistory[0] = String.valueOf(entry.remoteInputText);
1611 b.setRemoteInputHistory(newHistory);
1612
1613 Notification newNotification = b.build();
1614
1615 // Undo any compatibility view inflation
1616 newNotification.contentView = sbn.getNotification().contentView;
1617 newNotification.bigContentView = sbn.getNotification().bigContentView;
1618 newNotification.headsUpContentView = sbn.getNotification().headsUpContentView;
1619
1620 StatusBarNotification newSbn = new StatusBarNotification(sbn.getPackageName(),
1621 sbn.getOpPkg(),
1622 sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(),
1623 0, newNotification, sbn.getUser(), sbn.getPostTime());
1624
1625 updateNotification(newSbn, null);
1626 mKeysKeptForRemoteInput.add(entry.key);
1627 return;
1628 }
Selim Cinek684a4422015-04-15 16:18:39 -07001629 if (deferRemoval) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001630 mLatestRankingMap = ranking;
1631 mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
1632 return;
1633 }
Selim Cineka5703182016-05-11 21:23:16 -04001634 Entry entry = mNotificationData.get(key);
Adrian Roos18d099a2016-05-19 15:28:18 -07001635
Adrian Roos9550f2e2016-08-23 18:23:01 +02001636 if (entry != null && mRemoteInputController.isRemoteInputActive(entry)
1637 && (entry.row != null && !entry.row.isDismissed())) {
Adrian Roos18d099a2016-05-19 15:28:18 -07001638 mLatestRankingMap = ranking;
1639 mRemoteInputEntriesToRemoveOnCollapse.add(entry);
1640 return;
1641 }
1642
Selim Cineka5703182016-05-11 21:23:16 -04001643 if (entry != null && entry.row != null) {
Adrian Roosd009ab12016-05-20 17:58:53 -07001644 entry.row.setRemoved();
Selim Cineka5703182016-05-11 21:23:16 -04001645 }
Selim Cinek3f19f602016-05-02 18:01:56 -07001646 // Let's remove the children if this was a summary
1647 handleGroupSummaryRemoved(key, ranking);
Christoph Studer37fe6932014-05-26 13:10:30 +02001648 StatusBarNotification old = removeNotificationViews(key, ranking);
John Spurlockcd686b52013-06-05 10:13:46 -04001649 if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -04001650
1651 if (old != null) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001652 if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
Jorim Jaggiba94f882014-08-20 19:23:55 +02001653 && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02001654 if (mState == StatusBarState.SHADE) {
1655 animateCollapsePanels();
Selim Cinek61b350c2016-08-05 14:26:51 -07001656 } else if (mState == StatusBarState.SHADE_LOCKED && !isCollapsing()) {
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02001657 goToKeyguard();
1658 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -04001659 }
Joe Onorato808182d2010-07-09 18:52:06 -04001660 }
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001661 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001662 }
1663
Selim Cinek3f19f602016-05-02 18:01:56 -07001664 /**
1665 * Ensures that the group children are cancelled immediately when the group summary is cancelled
1666 * instead of waiting for the notification manager to send all cancels. Otherwise this could
1667 * lead to flickers.
1668 *
1669 * This also ensures that the animation looks nice and only consists of a single disappear
1670 * animation instead of multiple.
1671 *
1672 * @param key the key of the notification was removed
1673 * @param ranking the current ranking
1674 */
1675 private void handleGroupSummaryRemoved(String key,
1676 RankingMap ranking) {
1677 Entry entry = mNotificationData.get(key);
1678 if (entry != null && entry.row != null
1679 && entry.row.isSummaryWithChildren()) {
1680 if (entry.notification.getOverrideGroupKey() != null && !entry.row.isDismissed()) {
1681 // We don't want to remove children for autobundled notifications as they are not
1682 // always cancelled. We only remove them if they were dismissed by the user.
1683 return;
1684 }
Selim Cinek3f19f602016-05-02 18:01:56 -07001685 List<ExpandableNotificationRow> notificationChildren =
1686 entry.row.getNotificationChildren();
Selim Cinek1d359792017-01-13 14:43:43 -08001687 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
1688 for (int i = 0; i < notificationChildren.size(); i++) {
1689 ExpandableNotificationRow row = notificationChildren.get(i);
1690 if ((row.getStatusBarNotification().getNotification().flags
1691 & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
1692 // the child is a forground service notification which we can't remove!
1693 continue;
1694 }
1695 toRemove.add(row);
Selim Cinek3f19f602016-05-02 18:01:56 -07001696 toRemove.get(i).setKeepInParent(true);
Selim Cineka5703182016-05-11 21:23:16 -04001697 // we need to set this state earlier as otherwise we might generate some weird
1698 // animations
Adrian Roosd009ab12016-05-20 17:58:53 -07001699 toRemove.get(i).setRemoved();
Selim Cinek3f19f602016-05-02 18:01:56 -07001700 }
1701 for (int i = 0; i < toRemove.size(); i++) {
1702 removeNotification(toRemove.get(i).getStatusBarNotification().getKey(), ranking);
Selim Cinek7103fd42016-05-09 22:22:33 -04001703 // we need to ensure that the view is actually properly removed from the viewstate
1704 // as this won't happen anymore when kept in the parent.
1705 mStackScroller.removeViewStateForView(toRemove.get(i));
Selim Cinek3f19f602016-05-02 18:01:56 -07001706 }
1707 }
1708 }
1709
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001710 @Override
Selim Cinek5e018202016-12-15 14:44:36 -08001711 protected void performRemoveNotification(StatusBarNotification n) {
Adrian Roos18d099a2016-05-19 15:28:18 -07001712 Entry entry = mNotificationData.get(n.getKey());
1713 if (mRemoteInputController.isRemoteInputActive(entry)) {
Adrian Roos7813dd72016-09-23 17:12:17 -07001714 mRemoteInputController.removeRemoteInput(entry, null);
Adrian Roos18d099a2016-05-19 15:28:18 -07001715 }
Selim Cinek5e018202016-12-15 14:44:36 -08001716 super.performRemoveNotification(n);
Adrian Roos18d099a2016-05-19 15:28:18 -07001717 }
1718
1719 @Override
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001720 protected void refreshLayout(int layoutDirection) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001721 if (mNavigationBarView != null) {
1722 mNavigationBarView.setLayoutDirection(layoutDirection);
1723 }
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001724 }
1725
Christoph Studer37fe6932014-05-26 13:10:30 +02001726 private void updateNotificationShade() {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001727 if (mStackScroller == null) return;
Daniel Sandler26cda272012-05-22 15:44:08 -04001728
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001729 // Do not modify the notifications during collapse.
1730 if (isCollapsing()) {
1731 addPostCollapseAction(new Runnable() {
1732 @Override
1733 public void run() {
1734 updateNotificationShade();
1735 }
1736 });
1737 return;
1738 }
1739
Christoph Studerc8db24b2014-07-25 17:50:30 +02001740 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
Jorim Jaggif6411742014-08-05 17:10:43 +00001741 ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size());
Christoph Studerc8db24b2014-07-25 17:50:30 +02001742 final int N = activeNotifications.size();
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001743 for (int i=0; i<N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001744 Entry ent = activeNotifications.get(i);
Selim Cinekadd95262016-12-06 14:34:47 -08001745 if (ent.row.isDismissed() || ent.row.isRemoved()) {
1746 // we don't want to update removed notifications because they could
1747 // temporarily become children if they were isolated before.
1748 continue;
1749 }
Christoph Studerc8db24b2014-07-25 17:50:30 +02001750 int vis = ent.notification.getNotification().visibility;
Kenny Guy3a7c4a52014-03-03 18:24:03 +00001751
Christoph Studerc8db24b2014-07-25 17:50:30 +02001752 // Display public version of the notification if we need to redact.
Jorim Jaggiae441282014-08-01 02:45:18 +02001753 final boolean hideSensitive =
1754 !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId());
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001755 boolean sensitiveNote = vis == Notification.VISIBILITY_PRIVATE;
1756 boolean sensitivePackage = packageHasVisibilityOverride(ent.notification.getKey());
1757 boolean sensitive = (sensitiveNote && hideSensitive) || sensitivePackage;
1758 boolean showingPublic = sensitive && isLockscreenPublicMode();
Sudheer Shankaf5b850e2016-01-25 19:58:59 +00001759 if (showingPublic) {
1760 updatePublicContentView(ent, ent.notification);
1761 }
Selim Cinek3c76d502016-02-19 15:16:33 -08001762 ent.row.setSensitive(sensitive, hideSensitive);
Dan Sandler1b718782014-07-18 12:43:45 -04001763 if (ent.autoRedacted && ent.legacy) {
Jorim Jaggiae441282014-08-01 02:45:18 +02001764 // TODO: Also fade this? Or, maybe easier (and better), provide a dark redacted form
1765 // for legacy auto redacted notifications.
Dan Sandler1b718782014-07-18 12:43:45 -04001766 if (showingPublic) {
1767 ent.row.setShowingLegacyBackground(false);
1768 } else {
1769 ent.row.setShowingLegacyBackground(true);
1770 }
1771 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001772 if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
1773 ExpandableNotificationRow summary = mGroupManager.getGroupSummary(
1774 ent.row.getStatusBarNotification());
1775 List<ExpandableNotificationRow> orderedChildren =
1776 mTmpChildOrderMap.get(summary);
1777 if (orderedChildren == null) {
1778 orderedChildren = new ArrayList<>();
1779 mTmpChildOrderMap.put(summary, orderedChildren);
1780 }
1781 orderedChildren.add(ent.row);
1782 } else {
1783 toShow.add(ent.row);
1784 }
1785
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001786 }
1787
Selim Cinekef5127e2015-12-21 16:55:58 -08001788 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001789 for (int i=0; i< mStackScroller.getChildCount(); i++) {
1790 View child = mStackScroller.getChildAt(i);
Jorim Jaggif6411742014-08-05 17:10:43 +00001791 if (!toShow.contains(child) && child instanceof ExpandableNotificationRow) {
Selim Cinekef5127e2015-12-21 16:55:58 -08001792 toRemove.add((ExpandableNotificationRow) child);
Joe Onorato808182d2010-07-09 18:52:06 -04001793 }
1794 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001795
Selim Cinekef5127e2015-12-21 16:55:58 -08001796 for (ExpandableNotificationRow remove : toRemove) {
1797 if (mGroupManager.isChildInGroupWithSummary(remove.getStatusBarNotification())) {
1798 // we are only transfering this notification to its parent, don't generate an animation
1799 mStackScroller.setChildTransferInProgress(true);
1800 }
Selim Cinekc1e389d2016-04-07 11:02:57 -07001801 if (remove.isSummaryWithChildren()) {
1802 remove.removeAllChildren();
1803 }
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001804 mStackScroller.removeView(remove);
Selim Cinekef5127e2015-12-21 16:55:58 -08001805 mStackScroller.setChildTransferInProgress(false);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001806 }
Selim Cinek2b542422016-03-04 18:10:37 -08001807
1808 removeNotificationChildren();
1809
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001810 for (int i=0; i<toShow.size(); i++) {
1811 View v = toShow.get(i);
1812 if (v.getParent() == null) {
Selim Cinekadd95262016-12-06 14:34:47 -08001813 mVisualStabilityManager.notifyViewAddition(v);
Christoph Studer37fe6932014-05-26 13:10:30 +02001814 mStackScroller.addView(v);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001815 }
1816 }
Daniel Sandler26cda272012-05-22 15:44:08 -04001817
Selim Cinek2b542422016-03-04 18:10:37 -08001818 addNotificationChildrenAndSort();
1819
Christoph Studer37fe6932014-05-26 13:10:30 +02001820 // So after all this work notifications still aren't sorted correctly.
1821 // Let's do that now by advancing through toShow and mStackScroller in
1822 // lock-step, making sure mStackScroller matches what we see in toShow.
1823 int j = 0;
1824 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1825 View child = mStackScroller.getChildAt(i);
1826 if (!(child instanceof ExpandableNotificationRow)) {
1827 // We don't care about non-notification views.
1828 continue;
1829 }
1830
Selim Cinekb5605e52015-02-20 18:21:41 +01001831 ExpandableNotificationRow targetChild = toShow.get(j);
1832 if (child != targetChild) {
1833 // Oops, wrong notification at this position. Put the right one
1834 // here and advance both lists.
Selim Cinekadd95262016-12-06 14:34:47 -08001835 if (mVisualStabilityManager.canReorderNotification(targetChild)) {
1836 mStackScroller.changeViewPosition(targetChild, i);
1837 } else {
1838 mVisualStabilityManager.addReorderingAllowedCallback(this);
1839 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001840 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001841 j++;
Selim Cinekb5605e52015-02-20 18:21:41 +01001842
Christoph Studer37fe6932014-05-26 13:10:30 +02001843 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001844
Selim Cinekadd95262016-12-06 14:34:47 -08001845 mVisualStabilityManager.onReorderingFinished();
Selim Cinekb5605e52015-02-20 18:21:41 +01001846 // clear the map again for the next usage
1847 mTmpChildOrderMap.clear();
1848
Christoph Studer37fe6932014-05-26 13:10:30 +02001849 updateRowStates();
Jorim Jaggif6411742014-08-05 17:10:43 +00001850 updateSpeedbump();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001851 updateClearAll();
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001852 updateEmptyShadeView();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001853
Benjamin Franz27cf1462015-04-23 19:36:42 +01001854 updateQsExpansionEnabled();
1855 mShadeUpdates.check();
1856 }
1857
1858 /**
1859 * Disable QS if device not provisioned.
1860 * If the user switcher is simple then disable QS during setup because
1861 * the user intends to use the lock screen user switcher, QS in not needed.
1862 */
1863 private void updateQsExpansionEnabled() {
Jason Monk3ad242d2014-09-15 11:13:35 -04001864 mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned()
Adrian Roos2b154a92014-11-17 15:18:39 +01001865 && (mUserSetup || mUserSwitcherController == null
Benjamin Franz27cf1462015-04-23 19:36:42 +01001866 || !mUserSwitcherController.isSimpleUserSwitcher())
Adrian Roos21d2a252015-06-01 13:59:59 -07001867 && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
1868 && !ONLY_CORE_APPS);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001869 }
1870
Selim Cinek2b542422016-03-04 18:10:37 -08001871 private void addNotificationChildrenAndSort() {
Selim Cinek322ec7e2016-02-11 14:47:06 -08001872 // Let's now add all notification children which are missing
1873 boolean orderChanged = false;
1874 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1875 View view = mStackScroller.getChildAt(i);
1876 if (!(view instanceof ExpandableNotificationRow)) {
1877 // We don't care about non-notification views.
1878 continue;
1879 }
1880
1881 ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
1882 List<ExpandableNotificationRow> children = parent.getNotificationChildren();
1883 List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
1884
Selim Cinekb5605e52015-02-20 18:21:41 +01001885 for (int childIndex = 0; orderedChildren != null && childIndex < orderedChildren.size();
1886 childIndex++) {
1887 ExpandableNotificationRow childView = orderedChildren.get(childIndex);
1888 if (children == null || !children.contains(childView)) {
Selim Cinekadd95262016-12-06 14:34:47 -08001889 mVisualStabilityManager.notifyViewAddition(childView);
Selim Cinekb5605e52015-02-20 18:21:41 +01001890 parent.addChildNotification(childView, childIndex);
1891 mStackScroller.notifyGroupChildAdded(childView);
1892 }
1893 }
1894
1895 // Finally after removing and adding has been beformed we can apply the order.
Selim Cinekadd95262016-12-06 14:34:47 -08001896 orderChanged |= parent.applyChildOrder(orderedChildren, mVisualStabilityManager, this);
Selim Cinekb5605e52015-02-20 18:21:41 +01001897 }
1898 if (orderChanged) {
1899 mStackScroller.generateChildOrderChangedEvent();
1900 }
1901 }
1902
Selim Cinek2b542422016-03-04 18:10:37 -08001903 private void removeNotificationChildren() {
1904 // First let's remove all children which don't belong in the parents
1905 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
1906 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1907 View view = mStackScroller.getChildAt(i);
1908 if (!(view instanceof ExpandableNotificationRow)) {
1909 // We don't care about non-notification views.
1910 continue;
1911 }
1912
1913 ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
1914 List<ExpandableNotificationRow> children = parent.getNotificationChildren();
1915 List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
1916
1917 if (children != null) {
1918 toRemove.clear();
1919 for (ExpandableNotificationRow childRow : children) {
Selim Cinek3f19f602016-05-02 18:01:56 -07001920 if ((orderedChildren == null
1921 || !orderedChildren.contains(childRow))
1922 && !childRow.keepInParent()) {
Selim Cinek2b542422016-03-04 18:10:37 -08001923 toRemove.add(childRow);
1924 }
1925 }
1926 for (ExpandableNotificationRow remove : toRemove) {
1927 parent.removeChildNotification(remove);
1928 if (mNotificationData.get(remove.getStatusBarNotification().getKey()) == null) {
1929 // We only want to add an animation if the view is completely removed
1930 // otherwise it's just a transfer
Selim Cinekd1395642016-04-28 12:22:42 -07001931 mStackScroller.notifyGroupChildRemoved(remove,
1932 parent.getChildrenContainer());
Selim Cinek2b542422016-03-04 18:10:37 -08001933 }
1934 }
1935 }
1936 }
1937 }
1938
Jason Monk7e53f202016-01-28 10:40:20 -05001939 @Override
1940 public void addQsTile(ComponentName tile) {
1941 mQSPanel.getHost().addTile(tile);
1942 }
1943
1944 @Override
1945 public void remQsTile(ComponentName tile) {
1946 mQSPanel.getHost().removeTile(tile);
1947 }
1948
1949 @Override
1950 public void clickTile(ComponentName tile) {
1951 mQSPanel.clickTile(tile);
1952 }
1953
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001954 private boolean packageHasVisibilityOverride(String key) {
Julia Reynolds26fa8a52016-02-24 08:31:22 -05001955 return mNotificationData.getVisibilityOverride(key) == Notification.VISIBILITY_PRIVATE;
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001956 }
1957
Dan Sandlereceda3d2014-07-21 15:35:01 -04001958 private void updateClearAll() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001959 boolean showDismissView =
1960 mState != StatusBarState.KEYGUARD &&
Selim Cinek1d359792017-01-13 14:43:43 -08001961 hasActiveClearableNotifications();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001962 mStackScroller.updateDismissView(showDismissView);
1963 }
1964
Selim Cinek1d359792017-01-13 14:43:43 -08001965 /**
1966 * Return whether there are any clearable notifications
1967 */
1968 private boolean hasActiveClearableNotifications() {
1969 int childCount = mStackScroller.getChildCount();
1970 for (int i = 0; i < childCount; i++) {
1971 View child = mStackScroller.getChildAt(i);
1972 if (!(child instanceof ExpandableNotificationRow)) {
1973 continue;
1974 }
1975 if (((ExpandableNotificationRow) child).canViewBeDismissed()) {
1976 return true;
1977 }
1978 }
1979 return false;
1980 }
1981
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001982 private void updateEmptyShadeView() {
1983 boolean showEmptyShade =
1984 mState != StatusBarState.KEYGUARD &&
1985 mNotificationData.getActiveNotifications().size() == 0;
1986 mNotificationPanel.setShadeEmpty(showEmptyShade);
1987 }
1988
Jorim Jaggif6411742014-08-05 17:10:43 +00001989 private void updateSpeedbump() {
Selim Cinekadd95262016-12-06 14:34:47 -08001990 int speedBumpIndex = 0;
Jorim Jaggif6411742014-08-05 17:10:43 +00001991 int currentIndex = 0;
Selim Cinek2a739342016-03-17 10:28:55 -07001992 final int N = mStackScroller.getChildCount();
Jorim Jaggif6411742014-08-05 17:10:43 +00001993 for (int i = 0; i < N; i++) {
Selim Cinek2a739342016-03-17 10:28:55 -07001994 View view = mStackScroller.getChildAt(i);
1995 if (view.getVisibility() == View.GONE || !(view instanceof ExpandableNotificationRow)) {
Selim Cinekb5605e52015-02-20 18:21:41 +01001996 continue;
1997 }
Selim Cinek2a739342016-03-17 10:28:55 -07001998 ExpandableNotificationRow row = (ExpandableNotificationRow) view;
Jorim Jaggif6411742014-08-05 17:10:43 +00001999 currentIndex++;
Selim Cinekadd95262016-12-06 14:34:47 -08002000 if (!mNotificationData.isAmbient(row.getStatusBarNotification().getKey())) {
2001 speedBumpIndex = currentIndex;
2002 }
Jorim Jaggif6411742014-08-05 17:10:43 +00002003 }
Selim Cinekadd95262016-12-06 14:34:47 -08002004 mStackScroller.updateSpeedBumpIndex(speedBumpIndex);
Jorim Jaggif6411742014-08-05 17:10:43 +00002005 }
2006
Selim Cinekb5605e52015-02-20 18:21:41 +01002007 public static boolean isTopLevelChild(Entry entry) {
2008 return entry.row.getParent() instanceof NotificationStackScrollLayout;
2009 }
2010
Chris Wren0c8275b2012-05-08 13:36:48 -04002011 @Override
Christoph Studer37fe6932014-05-26 13:10:30 +02002012 protected void updateNotifications() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02002013 mNotificationData.filterAndSort();
2014
Christoph Studer37fe6932014-05-26 13:10:30 +02002015 updateNotificationShade();
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002016 mIconController.updateNotificationIcons(mNotificationData);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002017 }
2018
Selim Cinekef5127e2015-12-21 16:55:58 -08002019 public void requestNotificationUpdate() {
2020 updateNotifications();
2021 }
2022
Jorim Jaggi54045422014-07-03 18:30:40 +02002023 @Override
Chris Wren0c8275b2012-05-08 13:36:48 -04002024 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04002025
Chris Wren6d15a362013-08-20 18:46:29 -04002026 if (SPEW) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02002027 final boolean clearable = hasActiveNotifications() &&
Selim Cinek1d359792017-01-13 14:43:43 -08002028 hasActiveClearableNotifications();
Christoph Studerc8db24b2014-07-25 17:50:30 +02002029 Log.d(TAG, "setAreThereNotifications: N=" +
2030 mNotificationData.getActiveNotifications().size() + " any=" +
2031 hasActiveNotifications() + " clearable=" + clearable);
Daniel Sandler0761e4c2011-08-11 00:19:49 -04002032 }
2033
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002034 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
Christoph Studerc8db24b2014-07-25 17:50:30 +02002035 final boolean showDot = hasActiveNotifications() && !areLightsOn();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002036 if (showDot != (nlo.getAlpha() == 1.0f)) {
2037 if (showDot) {
2038 nlo.setAlpha(0f);
2039 nlo.setVisibility(View.VISIBLE);
2040 }
2041 nlo.animate()
2042 .alpha(showDot?1:0)
2043 .setDuration(showDot?750:250)
2044 .setInterpolator(new AccelerateInterpolator(2.0f))
2045 .setListener(showDot ? null : new AnimatorListenerAdapter() {
2046 @Override
2047 public void onAnimationEnd(Animator _a) {
2048 nlo.setVisibility(View.GONE);
2049 }
2050 })
2051 .start();
2052 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04002053
Dan Sandler16128f42014-05-21 12:48:22 -04002054 findAndUpdateMediaNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04002055 }
2056
Dan Sandler16128f42014-05-21 12:48:22 -04002057 public void findAndUpdateMediaNotifications() {
2058 boolean metaDataChanged = false;
2059
2060 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02002061 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
2062 final int N = activeNotifications.size();
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002063
2064 // Promote the media notification with a controller in 'playing' state, if any.
Dan Sandler16128f42014-05-21 12:48:22 -04002065 Entry mediaNotification = null;
2066 MediaController controller = null;
Christoph Studerc8db24b2014-07-25 17:50:30 +02002067 for (int i = 0; i < N; i++) {
2068 final Entry entry = activeNotifications.get(i);
Dan Sandler16128f42014-05-21 12:48:22 -04002069 if (isMediaNotification(entry)) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002070 final MediaSession.Token token =
2071 entry.notification.getNotification().extras
Dan Sandler16128f42014-05-21 12:48:22 -04002072 .getParcelable(Notification.EXTRA_MEDIA_SESSION);
2073 if (token != null) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002074 MediaController aController = new MediaController(mContext, token);
2075 if (PlaybackState.STATE_PLAYING ==
2076 getMediaControllerPlaybackState(aController)) {
2077 if (DEBUG_MEDIA) {
2078 Log.v(TAG, "DEBUG_MEDIA: found mediastyle controller matching "
2079 + entry.notification.getKey());
2080 }
Dan Sandler16128f42014-05-21 12:48:22 -04002081 mediaNotification = entry;
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002082 controller = aController;
2083 break;
Dan Sandler16128f42014-05-21 12:48:22 -04002084 }
2085 }
2086 }
2087 }
Dan Sandler16128f42014-05-21 12:48:22 -04002088 if (mediaNotification == null) {
2089 // Still nothing? OK, let's just look for live media sessions and see if they match
2090 // one of our notifications. This will catch apps that aren't (yet!) using media
2091 // notifications.
2092
2093 if (mMediaSessionManager != null) {
2094 final List<MediaController> sessions
2095 = mMediaSessionManager.getActiveSessionsForUser(
2096 null,
2097 UserHandle.USER_ALL);
2098
2099 for (MediaController aController : sessions) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002100 if (PlaybackState.STATE_PLAYING ==
2101 getMediaControllerPlaybackState(aController)) {
2102 // now to see if we have one like this
2103 final String pkg = aController.getPackageName();
Dan Sandler16128f42014-05-21 12:48:22 -04002104
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002105 for (int i = 0; i < N; i++) {
2106 final Entry entry = activeNotifications.get(i);
2107 if (entry.notification.getPackageName().equals(pkg)) {
2108 if (DEBUG_MEDIA) {
2109 Log.v(TAG, "DEBUG_MEDIA: found controller matching "
2110 + entry.notification.getKey());
Dan Sandler16128f42014-05-21 12:48:22 -04002111 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002112 controller = aController;
2113 mediaNotification = entry;
2114 break;
Dan Sandler16128f42014-05-21 12:48:22 -04002115 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002116 }
Dan Sandler16128f42014-05-21 12:48:22 -04002117 }
2118 }
2119 }
2120 }
2121
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002122 if (controller != null && !sameSessions(mMediaController, controller)) {
Dan Sandler16128f42014-05-21 12:48:22 -04002123 // We have a new media session
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002124 clearCurrentMediaNotification();
Dan Sandler16128f42014-05-21 12:48:22 -04002125 mMediaController = controller;
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002126 mMediaController.registerCallback(mMediaListener);
2127 mMediaMetadata = mMediaController.getMetadata();
Dan Sandler16128f42014-05-21 12:48:22 -04002128 if (DEBUG_MEDIA) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002129 Log.v(TAG, "DEBUG_MEDIA: insert listener, receive metadata: "
2130 + mMediaMetadata);
Dan Sandler16128f42014-05-21 12:48:22 -04002131 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002132
2133 if (mediaNotification != null) {
2134 mMediaNotificationKey = mediaNotification.notification.getKey();
2135 if (DEBUG_MEDIA) {
2136 Log.v(TAG, "DEBUG_MEDIA: Found new media notification: key="
2137 + mMediaNotificationKey + " controller=" + mMediaController);
2138 }
2139 }
2140 metaDataChanged = true;
Dan Sandler16128f42014-05-21 12:48:22 -04002141 }
2142 }
2143
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002144 if (metaDataChanged) {
2145 updateNotifications();
2146 }
Adrian Roos52738322016-01-29 08:49:21 -08002147 updateMediaMetaData(metaDataChanged, true);
Dan Sandler16128f42014-05-21 12:48:22 -04002148 }
2149
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002150 private int getMediaControllerPlaybackState(MediaController controller) {
2151 if (controller != null) {
2152 final PlaybackState playbackState = controller.getPlaybackState();
2153 if (playbackState != null) {
2154 return playbackState.getState();
2155 }
2156 }
2157 return PlaybackState.STATE_NONE;
2158 }
2159
2160 private boolean isPlaybackActive(int state) {
2161 if (state != PlaybackState.STATE_STOPPED
2162 && state != PlaybackState.STATE_ERROR
2163 && state != PlaybackState.STATE_NONE) {
2164 return true;
2165 }
2166 return false;
2167 }
2168
2169 private void clearCurrentMediaNotification() {
2170 mMediaNotificationKey = null;
2171 mMediaMetadata = null;
2172 if (mMediaController != null) {
2173 if (DEBUG_MEDIA) {
2174 Log.v(TAG, "DEBUG_MEDIA: Disconnecting from old controller: "
2175 + mMediaController.getPackageName());
2176 }
2177 mMediaController.unregisterCallback(mMediaListener);
2178 }
2179 mMediaController = null;
2180 }
2181
Christoph Studerb5245d82014-09-19 16:54:36 +02002182 private boolean sameSessions(MediaController a, MediaController b) {
2183 if (a == b) return true;
2184 if (a == null) return false;
2185 return a.controlsSameSession(b);
2186 }
2187
Dan Sandler16128f42014-05-21 12:48:22 -04002188 /**
Dan Sandler7dea0ee2014-07-21 21:07:15 -04002189 * Hide the album artwork that is fading out and release its bitmap.
Dan Sandler16128f42014-05-21 12:48:22 -04002190 */
2191 private Runnable mHideBackdropFront = new Runnable() {
2192 @Override
2193 public void run() {
2194 if (DEBUG_MEDIA) {
2195 Log.v(TAG, "DEBUG_MEDIA: removing fade layer");
2196 }
2197 mBackdropFront.setVisibility(View.INVISIBLE);
Dan Sandler7dea0ee2014-07-21 21:07:15 -04002198 mBackdropFront.animate().cancel();
2199 mBackdropFront.setImageDrawable(null);
Dan Sandler16128f42014-05-21 12:48:22 -04002200 }
2201 };
2202
2203 /**
Adrian Roose381c162016-02-11 15:26:42 -08002204 * Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper.
Dan Sandler16128f42014-05-21 12:48:22 -04002205 */
Adrian Roos52738322016-01-29 08:49:21 -08002206 public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07002207 Trace.beginSection("PhoneStatusBar#updateMediaMetaData");
2208 if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) {
2209 Trace.endSection();
2210 return;
2211 }
Dan Sandler16128f42014-05-21 12:48:22 -04002212
Nick Desaulniers1d396752016-07-25 15:05:33 -07002213 if (mBackdrop == null) {
2214 Trace.endSection();
2215 return; // called too early
2216 }
Dan Sandler16128f42014-05-21 12:48:22 -04002217
Selim Cinek37c110f2015-05-22 12:38:44 -07002218 if (mLaunchTransitionFadingAway) {
2219 mBackdrop.setVisibility(View.INVISIBLE);
Nick Desaulniers1d396752016-07-25 15:05:33 -07002220 Trace.endSection();
Selim Cinek37c110f2015-05-22 12:38:44 -07002221 return;
2222 }
2223
Dan Sandler16128f42014-05-21 12:48:22 -04002224 if (DEBUG_MEDIA) {
2225 Log.v(TAG, "DEBUG_MEDIA: updating album art for notification " + mMediaNotificationKey
Selim Cinek131c1e22015-05-11 19:04:49 -07002226 + " metadata=" + mMediaMetadata
2227 + " metaDataChanged=" + metaDataChanged
2228 + " state=" + mState);
Dan Sandler16128f42014-05-21 12:48:22 -04002229 }
2230
Adrian Roos3b777cb2016-04-14 12:04:28 -07002231 Drawable artworkDrawable = null;
Dan Sandler16128f42014-05-21 12:48:22 -04002232 if (mMediaMetadata != null) {
Adrian Roos3b777cb2016-04-14 12:04:28 -07002233 Bitmap artworkBitmap = null;
Dan Sandler16128f42014-05-21 12:48:22 -04002234 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
2235 if (artworkBitmap == null) {
2236 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
2237 // might still be null
2238 }
Adrian Roos3b777cb2016-04-14 12:04:28 -07002239 if (artworkBitmap != null) {
2240 artworkDrawable = new BitmapDrawable(mBackdropBack.getResources(), artworkBitmap);
2241 }
Dan Sandler16128f42014-05-21 12:48:22 -04002242 }
Adrian Roosa3760a42016-04-25 16:21:06 -07002243 boolean allowWhenShade = false;
Adrian Roos3b777cb2016-04-14 12:04:28 -07002244 if (ENABLE_LOCKSCREEN_WALLPAPER && artworkDrawable == null) {
2245 Bitmap lockWallpaper = mLockscreenWallpaper.getBitmap();
2246 if (lockWallpaper != null) {
2247 artworkDrawable = new LockscreenWallpaper.WallpaperDrawable(
2248 mBackdropBack.getResources(), lockWallpaper);
Adrian Roosa3760a42016-04-25 16:21:06 -07002249 // We're in the SHADE mode on the SIM screen - yet we still need to show
2250 // the lockscreen wallpaper in that mode.
2251 allowWhenShade = mStatusBarKeyguardViewManager != null
2252 && mStatusBarKeyguardViewManager.isShowing();
Adrian Roos3b777cb2016-04-14 12:04:28 -07002253 }
Adrian Roos52738322016-01-29 08:49:21 -08002254 }
Dan Sandler16128f42014-05-21 12:48:22 -04002255
Adrian Roosa3760a42016-04-25 16:21:06 -07002256 boolean hideBecauseOccluded = mStatusBarKeyguardViewManager != null
2257 && mStatusBarKeyguardViewManager.isOccluded();
2258
Adrian Roos3b777cb2016-04-14 12:04:28 -07002259 final boolean hasArtwork = artworkDrawable != null;
Dan Sandler16128f42014-05-21 12:48:22 -04002260
Adrian Roosa3760a42016-04-25 16:21:06 -07002261 if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
2262 && (mState != StatusBarState.SHADE || allowWhenShade)
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002263 && mFingerprintUnlockController.getMode()
Adrian Roosa3760a42016-04-25 16:21:06 -07002264 != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
2265 && !hideBecauseOccluded) {
Dan Sandler16128f42014-05-21 12:48:22 -04002266 // time to show some art!
2267 if (mBackdrop.getVisibility() != View.VISIBLE) {
2268 mBackdrop.setVisibility(View.VISIBLE);
Adrian Roos52738322016-01-29 08:49:21 -08002269 if (allowEnterAnimation) {
Jorim Jaggi6626f542016-08-22 13:08:44 -07002270 mBackdrop.setAlpha(SRC_MIN_ALPHA);
2271 mBackdrop.animate().alpha(1f);
Adrian Roos52738322016-01-29 08:49:21 -08002272 } else {
2273 mBackdrop.animate().cancel();
2274 mBackdrop.setAlpha(1f);
2275 }
Jorim Jaggi6626f542016-08-22 13:08:44 -07002276 mStatusBarWindowManager.setBackdropShowing(true);
Dan Sandler16128f42014-05-21 12:48:22 -04002277 metaDataChanged = true;
2278 if (DEBUG_MEDIA) {
2279 Log.v(TAG, "DEBUG_MEDIA: Fading in album artwork");
2280 }
2281 }
2282 if (metaDataChanged) {
2283 if (mBackdropBack.getDrawable() != null) {
Julia Reynolds4b9658a2015-07-22 17:07:42 -04002284 Drawable drawable =
Adrian Roos751f33f2016-04-19 16:41:18 -07002285 mBackdropBack.getDrawable().getConstantState()
2286 .newDrawable(mBackdropFront.getResources()).mutate();
Selim Cineka0fad3b2014-09-19 17:20:05 +02002287 mBackdropFront.setImageDrawable(drawable);
Jorim Jaggi0e664392014-09-27 01:30:22 +02002288 if (mScrimSrcModeEnabled) {
2289 mBackdropFront.getDrawable().mutate().setXfermode(mSrcOverXferMode);
2290 }
Dan Sandler16128f42014-05-21 12:48:22 -04002291 mBackdropFront.setAlpha(1f);
2292 mBackdropFront.setVisibility(View.VISIBLE);
2293 } else {
2294 mBackdropFront.setVisibility(View.INVISIBLE);
2295 }
2296
2297 if (DEBUG_MEDIA_FAKE_ARTWORK) {
2298 final int c = 0xFF000000 | (int)(Math.random() * 0xFFFFFF);
2299 Log.v(TAG, String.format("DEBUG_MEDIA: setting new color: 0x%08x", c));
2300 mBackdropBack.setBackgroundColor(0xFFFFFFFF);
2301 mBackdropBack.setImageDrawable(new ColorDrawable(c));
2302 } else {
Adrian Roos3b777cb2016-04-14 12:04:28 -07002303 mBackdropBack.setImageDrawable(artworkDrawable);
Dan Sandler16128f42014-05-21 12:48:22 -04002304 }
Jorim Jaggi0e664392014-09-27 01:30:22 +02002305 if (mScrimSrcModeEnabled) {
2306 mBackdropBack.getDrawable().mutate().setXfermode(mSrcXferMode);
2307 }
Dan Sandler16128f42014-05-21 12:48:22 -04002308
2309 if (mBackdropFront.getVisibility() == View.VISIBLE) {
2310 if (DEBUG_MEDIA) {
2311 Log.v(TAG, "DEBUG_MEDIA: Crossfading album artwork from "
2312 + mBackdropFront.getDrawable()
2313 + " to "
2314 + mBackdropBack.getDrawable());
2315 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02002316 mBackdropFront.animate()
Dan Sandler16128f42014-05-21 12:48:22 -04002317 .setDuration(250)
2318 .alpha(0f).withEndAction(mHideBackdropFront);
2319 }
2320 }
2321 } else {
2322 // need to hide the album art, either because we are unlocked or because
2323 // the metadata isn't there to support it
2324 if (mBackdrop.getVisibility() != View.GONE) {
2325 if (DEBUG_MEDIA) {
2326 Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
2327 }
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002328 if (mFingerprintUnlockController.getMode()
Adrian Roosa3760a42016-04-25 16:21:06 -07002329 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
2330 || hideBecauseOccluded) {
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02002331
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002332 // We are unlocking directly - no animation!
2333 mBackdrop.setVisibility(View.GONE);
Vadim Trysheve7d7d572016-03-09 16:44:30 -08002334 mBackdropBack.setImageDrawable(null);
Adrian Roosd5c2db62016-03-08 16:11:31 -08002335 mStatusBarWindowManager.setBackdropShowing(false);
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002336 } else {
Adrian Roosd5c2db62016-03-08 16:11:31 -08002337 mStatusBarWindowManager.setBackdropShowing(false);
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002338 mBackdrop.animate()
Jorim Jaggi6626f542016-08-22 13:08:44 -07002339 .alpha(SRC_MIN_ALPHA)
Selim Cinekc18010f2016-01-20 13:41:30 -08002340 .setInterpolator(Interpolators.ACCELERATE_DECELERATE)
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002341 .setDuration(300)
2342 .setStartDelay(0)
2343 .withEndAction(new Runnable() {
2344 @Override
2345 public void run() {
2346 mBackdrop.setVisibility(View.GONE);
2347 mBackdropFront.animate().cancel();
Vadim Trysheve7d7d572016-03-09 16:44:30 -08002348 mBackdropBack.setImageDrawable(null);
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002349 mHandler.post(mHideBackdropFront);
2350 }
2351 });
2352 if (mKeyguardFadingAway) {
2353 mBackdrop.animate()
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002354 // Make it disappear faster, as the focus should be on the activity
2355 // behind.
2356 .setDuration(mKeyguardFadingAwayDuration / 2)
2357 .setStartDelay(mKeyguardFadingAwayDelay)
Selim Cinekc18010f2016-01-20 13:41:30 -08002358 .setInterpolator(Interpolators.LINEAR)
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002359 .start();
2360 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02002361 }
Dan Sandler16128f42014-05-21 12:48:22 -04002362 }
2363 }
Nick Desaulniers1d396752016-07-25 15:05:33 -07002364 Trace.endSection();
Dan Sandler16128f42014-05-21 12:48:22 -04002365 }
2366
Adrian Roos7bb38a92016-07-21 11:44:01 -07002367 private void updateReportRejectedTouchVisibility() {
2368 if (mReportRejectedTouch == null) {
2369 return;
2370 }
2371 mReportRejectedTouch.setVisibility(mState == StatusBarState.KEYGUARD
2372 && mFalsingManager.isReportingEnabled() ? View.VISIBLE : View.INVISIBLE);
2373 }
2374
Xiaohui Cheneb04a992016-03-22 14:58:03 -07002375 protected int adjustDisableFlags(int state) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07002376 if (!mLaunchTransitionFadingAway && !mKeyguardFadingAway
Selim Cinekbaa23272014-07-08 18:01:07 +02002377 && (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
Jorim Jaggib13d36d2014-06-06 18:03:52 +02002378 state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
2379 state |= StatusBarManager.DISABLE_SYSTEM_INFO;
2380 }
Adrian Roos316bf542016-08-23 17:53:07 +02002381 if (mNetworkController != null && EncryptionHelper.IS_DATA_ENCRYPTED) {
2382 if (mNetworkController.hasEmergencyCryptKeeperText()) {
2383 state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
2384 }
2385 if (!mNetworkController.isRadioOn()) {
2386 state |= StatusBarManager.DISABLE_SYSTEM_INFO;
2387 }
2388 }
Jorim Jaggib13d36d2014-06-06 18:03:52 +02002389 return state;
2390 }
2391
Joe Onorato808182d2010-07-09 18:52:06 -04002392 /**
2393 * State is one or more of the DISABLE constants from StatusBarManager.
2394 */
Jim Miller07e03842016-06-22 15:18:13 -07002395 @Override
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002396 public void disable(int state1, int state2, boolean animate) {
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002397 animate &= mStatusBarWindowState != WINDOW_STATE_HIDDEN;
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002398 mDisabledUnmodified1 = state1;
2399 mDisabledUnmodified2 = state2;
2400 state1 = adjustDisableFlags(state1);
2401 final int old1 = mDisabled1;
2402 final int diff1 = state1 ^ old1;
2403 mDisabled1 = state1;
2404
2405 final int old2 = mDisabled2;
2406 final int diff2 = state2 ^ old2;
2407 mDisabled2 = state2;
Joe Onorato808182d2010-07-09 18:52:06 -04002408
Daniel Sandlere21f2882011-08-18 10:14:59 -04002409 if (DEBUG) {
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002410 Log.d(TAG, String.format("disable1: 0x%08x -> 0x%08x (diff1: 0x%08x)",
2411 old1, state1, diff1));
2412 Log.d(TAG, String.format("disable2: 0x%08x -> 0x%08x (diff2: 0x%08x)",
2413 old2, state2, diff2));
Daniel Sandlere21f2882011-08-18 10:14:59 -04002414 }
2415
Daniel Sandler6da2b762011-09-14 16:04:59 -04002416 StringBuilder flagdbg = new StringBuilder();
2417 flagdbg.append("disable: < ");
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002418 flagdbg.append(((state1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
2419 flagdbg.append(((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
2420 flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
2421 flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
2422 flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
2423 flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
2424 flagdbg.append(((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
2425 flagdbg.append(((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
2426 flagdbg.append(((state1 & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
2427 flagdbg.append(((diff1 & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
2428 flagdbg.append(((state1 & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
2429 flagdbg.append(((diff1 & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
2430 flagdbg.append(((state1 & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
2431 flagdbg.append(((diff1 & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
2432 flagdbg.append(((state1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
2433 flagdbg.append(((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
2434 flagdbg.append(((state1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
2435 flagdbg.append(((diff1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
Benjamin Franz27cf1462015-04-23 19:36:42 +01002436 flagdbg.append(((state2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "QUICK_SETTINGS"
2437 : "quick_settings");
2438 flagdbg.append(((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04002439 flagdbg.append(">");
John Spurlockcd686b52013-06-05 10:13:46 -04002440 Log.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07002441
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002442 if ((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
2443 if ((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002444 mIconController.hideSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04002445 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002446 mIconController.showSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04002447 }
2448 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04002449
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002450 if ((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) {
2451 boolean visible = (state1 & StatusBarManager.DISABLE_CLOCK) == 0;
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002452 mIconController.setClockVisibility(visible);
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07002453 }
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002454 if ((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) {
2455 if ((state1 & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002456 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04002457 }
2458 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04002459
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002460 if ((diff1 & (StatusBarManager.DISABLE_HOME
Jim Miller5e6af442011-12-02 18:24:26 -08002461 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerd5483c32012-10-19 16:44:15 -04002462 | StatusBarManager.DISABLE_BACK
2463 | StatusBarManager.DISABLE_SEARCH)) != 0) {
Daniel Sandlerdba93562011-10-06 16:39:58 -04002464 // the nav bar will take care of these
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002465 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state1);
Daniel Sandler6da2b762011-09-14 16:04:59 -04002466
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002467 if ((state1 & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04002468 // close recents if it's visible
Winson Chung1e8d71b2014-05-16 17:05:22 -07002469 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
2470 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
Daniel Sandler6da2b762011-09-14 16:04:59 -04002471 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04002472 }
2473
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002474 if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
2475 if ((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002476 mIconController.hideNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04002477 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002478 mIconController.showNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04002479 }
Joe Onorato808182d2010-07-09 18:52:06 -04002480 }
Jason Monkf7019542014-07-31 12:42:25 -04002481
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002482 if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
Jason Monkf7019542014-07-31 12:42:25 -04002483 mDisableNotificationAlerts =
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002484 (state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
Jason Monkf7019542014-07-31 12:42:25 -04002485 mHeadsUpObserver.onChange(true);
2486 }
Benjamin Franz27cf1462015-04-23 19:36:42 +01002487
2488 if ((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) {
2489 updateQsExpansionEnabled();
2490 }
Joe Onorato808182d2010-07-09 18:52:06 -04002491 }
2492
Adrian Roos316bf542016-08-23 17:53:07 +02002493 /**
2494 * Reapplies the disable flags as last requested by StatusBarManager.
2495 *
2496 * This needs to be called if state used by {@link #adjustDisableFlags} changes.
2497 */
2498 private void recomputeDisableFlags(boolean animate) {
2499 disable(mDisabledUnmodified1, mDisabledUnmodified2, animate);
2500 }
2501
Michael Jurka7f2668c2012-03-27 07:49:52 -07002502 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07002503 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07002504 return new PhoneStatusBar.H();
2505 }
2506
Jorim Jaggi97b63c42014-05-02 23:03:34 +02002507 @Override
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02002508 public void startActivity(Intent intent, boolean dismissShade) {
2509 startActivityDismissingKeyguard(intent, false, dismissShade);
Jorim Jaggi97b63c42014-05-02 23:03:34 +02002510 }
2511
Selim Cineke70d6532015-04-24 16:46:13 -07002512 @Override
Jorim Jaggid9449862015-05-29 14:49:08 -07002513 public void startActivity(Intent intent, boolean dismissShade, Callback callback) {
2514 startActivityDismissingKeyguard(intent, false, dismissShade, callback);
2515 }
2516
2517 @Override
Selim Cineke70d6532015-04-24 16:46:13 -07002518 public void preventNextAnimation() {
2519 overrideActivityPendingAppTransition(true /* keyguardShowing */);
2520 }
2521
Jorim Jaggib690f0d2014-07-03 23:25:44 +02002522 public void setQsExpanded(boolean expanded) {
2523 mStatusBarWindowManager.setQsExpanded(expanded);
Adrian Roos4c7d9602015-06-10 13:44:48 -07002524 mKeyguardStatusView.setImportantForAccessibility(expanded
2525 ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
2526 : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
Jorim Jaggib690f0d2014-07-03 23:25:44 +02002527 }
2528
Jorim Jaggi84a3e7a2014-08-13 17:58:58 +02002529 public boolean isGoingToNotificationShade() {
2530 return mLeaveOpenOnKeyguardHide;
2531 }
2532
Jorim Jaggid692dd02014-08-14 20:57:42 +02002533 public boolean isQsExpanded() {
2534 return mNotificationPanel.isQsExpanded();
2535 }
2536
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07002537 public boolean isWakeUpComingFromTouch() {
2538 return mWakeUpComingFromTouch;
Selim Cinek29ed3c92014-09-23 20:44:35 +02002539 }
2540
Selim Cinek19c8c702014-08-25 22:09:19 +02002541 public boolean isFalsingThresholdNeeded() {
Selim Cinek9db71052015-04-24 18:54:30 -07002542 return getBarState() == StatusBarState.KEYGUARD;
Selim Cinek19c8c702014-08-25 22:09:19 +02002543 }
2544
John Spurlock0b99ea92014-10-01 15:32:22 -04002545 public boolean isDozing() {
2546 return mDozing;
2547 }
2548
Christoph Studer2e731b52014-08-22 16:01:51 +02002549 @Override // NotificationData.Environment
2550 public String getCurrentMediaNotificationKey() {
2551 return mMediaNotificationKey;
2552 }
2553
Jorim Jaggi0e664392014-09-27 01:30:22 +02002554 public boolean isScrimSrcModeEnabled() {
2555 return mScrimSrcModeEnabled;
2556 }
2557
Joe Onorato808182d2010-07-09 18:52:06 -04002558 /**
Christoph Studer2231c6e2014-12-19 12:40:13 +01002559 * To be called when there's a state change in StatusBarKeyguardViewManager.
2560 */
2561 public void onKeyguardViewManagerStatesUpdated() {
2562 logStateToEventlog();
2563 }
2564
2565 @Override // UnlockMethodCache.OnUnlockMethodChangedListener
2566 public void onUnlockMethodStateChanged() {
2567 logStateToEventlog();
2568 }
2569
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002570 @Override
John Spurlockb349af572015-04-29 12:24:19 -04002571 public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
Selim Cinek684a4422015-04-15 16:18:39 -07002572 if (inPinnedMode) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002573 mStatusBarWindowManager.setHeadsUpShowing(true);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002574 mStatusBarWindowManager.setForceStatusBarVisible(true);
Selim Cinek131c1e22015-05-11 19:04:49 -07002575 if (mNotificationPanel.isFullyCollapsed()) {
2576 // We need to ensure that the touchable region is updated before the window will be
2577 // resized, in order to not catch any touches. A layout will ensure that
2578 // onComputeInternalInsets will be called and after that we can resize the layout. Let's
2579 // make sure that the window stays small for one frame until the touchableRegion is set.
2580 mNotificationPanel.requestLayout();
2581 mStatusBarWindowManager.setForceWindowCollapsed(true);
2582 mNotificationPanel.post(new Runnable() {
2583 @Override
2584 public void run() {
2585 mStatusBarWindowManager.setForceWindowCollapsed(false);
2586 }
2587 });
2588 }
Selim Cinek737bff32015-05-08 16:08:35 -07002589 } else {
Selim Cinek131c1e22015-05-11 19:04:49 -07002590 if (!mNotificationPanel.isFullyCollapsed() || mNotificationPanel.isTracking()) {
2591 // We are currently tracking or is open and the shade doesn't need to be kept
2592 // open artificially.
Selim Cinek737bff32015-05-08 16:08:35 -07002593 mStatusBarWindowManager.setHeadsUpShowing(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002594 } else {
Selim Cinek131c1e22015-05-11 19:04:49 -07002595 // we need to keep the panel open artificially, let's wait until the animation
2596 // is finished.
Selim Cinek737bff32015-05-08 16:08:35 -07002597 mHeadsUpManager.setHeadsUpGoingAway(true);
2598 mStackScroller.runAfterAnimationFinished(new Runnable() {
2599 @Override
2600 public void run() {
2601 if (!mHeadsUpManager.hasPinnedHeadsUp()) {
2602 mStatusBarWindowManager.setHeadsUpShowing(false);
2603 mHeadsUpManager.setHeadsUpGoingAway(false);
2604 }
Adrian Roos9550f2e2016-08-23 18:23:01 +02002605 removeRemoteInputEntriesKeptUntilCollapsed();
Selim Cinek737bff32015-05-08 16:08:35 -07002606 }
2607 });
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002608 }
2609 }
2610 }
2611
2612 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002613 public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
John Spurlockb349af572015-04-29 12:24:19 -04002614 dismissVolumeDialog();
Selim Cinek1f3f5442015-04-10 17:54:46 -07002615 }
2616
2617 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002618 public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
2619 }
2620
2621 @Override
2622 public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002623 if (!isHeadsUp && mHeadsUpEntriesToRemoveOnSwitch.contains(entry)) {
2624 removeNotification(entry.key, mLatestRankingMap);
2625 mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
2626 if (mHeadsUpEntriesToRemoveOnSwitch.isEmpty()) {
2627 mLatestRankingMap = null;
2628 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07002629 } else {
2630 updateNotificationRanking(null);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002631 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07002632
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002633 }
2634
Jim Miller07e03842016-06-22 15:18:13 -07002635 @Override
Chris Wrenbdf33762015-12-04 15:50:51 -05002636 protected void updateHeadsUp(String key, Entry entry, boolean shouldPeek,
Selim Cinek29fa89b2015-04-17 10:39:11 -07002637 boolean alertAgain) {
2638 final boolean wasHeadsUp = isHeadsUp(key);
2639 if (wasHeadsUp) {
Chris Wrenbdf33762015-12-04 15:50:51 -05002640 if (!shouldPeek) {
Selim Cinek29fa89b2015-04-17 10:39:11 -07002641 // We don't want this to be interrupting anymore, lets remove it
Adrian Roosc721fcc52016-04-29 11:28:37 -07002642 mHeadsUpManager.removeNotification(key, false /* ignoreEarliestRemovalTime */);
Selim Cinek684a4422015-04-15 16:18:39 -07002643 } else {
2644 mHeadsUpManager.updateNotification(entry, alertAgain);
Selim Cinek29fa89b2015-04-17 10:39:11 -07002645 }
Chris Wrenbdf33762015-12-04 15:50:51 -05002646 } else if (shouldPeek && alertAgain) {
Selim Cinek29fa89b2015-04-17 10:39:11 -07002647 // This notification was updated to be a heads-up, show it!
2648 mHeadsUpManager.showNotification(entry);
2649 }
2650 }
2651
Jim Miller07e03842016-06-22 15:18:13 -07002652 @Override
Selim Cinek29fa89b2015-04-17 10:39:11 -07002653 protected void setHeadsUpUser(int newUserId) {
2654 if (mHeadsUpManager != null) {
2655 mHeadsUpManager.setUser(newUserId);
2656 }
2657 }
2658
2659 public boolean isHeadsUp(String key) {
2660 return mHeadsUpManager.isHeadsUp(key);
2661 }
2662
Jim Miller07e03842016-06-22 15:18:13 -07002663 @Override
Selim Cinek29fa89b2015-04-17 10:39:11 -07002664 protected boolean isSnoozedPackage(StatusBarNotification sbn) {
2665 return mHeadsUpManager.isSnoozed(sbn.getPackageName());
2666 }
2667
Selim Cineke70d6532015-04-24 16:46:13 -07002668 public boolean isKeyguardCurrentlySecure() {
Selim Cineke8bae622015-07-15 13:24:06 -07002669 return !mUnlockMethodCache.canSkipBouncer();
Selim Cineke70d6532015-04-24 16:46:13 -07002670 }
2671
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002672 public void setPanelExpanded(boolean isExpanded) {
2673 mStatusBarWindowManager.setPanelExpanded(isExpanded);
Selim Cinekadd95262016-12-06 14:34:47 -08002674 mVisualStabilityManager.setPanelExpanded(isExpanded);
Adrian Roos18d099a2016-05-19 15:28:18 -07002675 if (isExpanded && getBarState() != StatusBarState.KEYGUARD) {
2676 if (DEBUG) {
2677 Log.v(TAG, "clearing notification effects from setPanelExpanded");
2678 }
2679 clearNotificationEffects();
2680 }
2681
2682 if (!isExpanded) {
2683 removeRemoteInputEntriesKeptUntilCollapsed();
2684 }
2685 }
2686
2687 private void removeRemoteInputEntriesKeptUntilCollapsed() {
2688 for (int i = 0; i < mRemoteInputEntriesToRemoveOnCollapse.size(); i++) {
2689 Entry entry = mRemoteInputEntriesToRemoveOnCollapse.valueAt(i);
Adrian Roos7813dd72016-09-23 17:12:17 -07002690 mRemoteInputController.removeRemoteInput(entry, null);
Adrian Roos18d099a2016-05-19 15:28:18 -07002691 removeNotification(entry.key, mLatestRankingMap);
2692 }
2693 mRemoteInputEntriesToRemoveOnCollapse.clear();
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002694 }
2695
Adrian Roos401caae2016-03-04 13:35:21 -08002696 public void onScreenTurnedOff() {
2697 mFalsingManager.onScreenOff();
2698 }
2699
Selim Cinekadd95262016-12-06 14:34:47 -08002700 @Override
2701 public void onReorderingAllowed() {
2702 updateNotifications();
2703 }
2704
Christoph Studer2231c6e2014-12-19 12:40:13 +01002705 /**
Joe Onorato808182d2010-07-09 18:52:06 -04002706 * All changes to the status bar and notifications funnel through here and are batched.
2707 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07002708 private class H extends BaseStatusBar.H {
Jim Miller07e03842016-06-22 15:18:13 -07002709 @Override
Joe Onorato808182d2010-07-09 18:52:06 -04002710 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07002711 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04002712 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002713 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04002714 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002715 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04002716 case MSG_OPEN_SETTINGS_PANEL:
Jason Monka9927322015-12-13 16:22:37 -05002717 animateExpandSettingsPanel((String) m.obj);
Daniel Sandler11cf1782012-09-27 14:03:08 -04002718 break;
2719 case MSG_CLOSE_PANELS:
2720 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002721 break;
Jorim Jaggi826730a2014-12-08 21:05:13 +01002722 case MSG_LAUNCH_TRANSITION_TIMEOUT:
2723 onLaunchTransitionTimeout();
2724 break;
Chris Wrene97f90b2013-08-07 17:39:35 -04002725 }
2726 }
2727 }
2728
Chris Wren930ecca2014-11-12 17:43:41 -05002729 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002730 public void maybeEscalateHeadsUp() {
Selim Cinek3362c132016-02-11 15:43:03 -08002731 Collection<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getAllEntries();
Selim Cineka59ecc32015-04-07 10:51:49 -07002732 for (HeadsUpManager.HeadsUpEntry entry : entries) {
2733 final StatusBarNotification sbn = entry.entry.notification;
Chris Wrene97f90b2013-08-07 17:39:35 -04002734 final Notification notification = sbn.getNotification();
2735 if (notification.fullScreenIntent != null) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002736 if (DEBUG) {
Chris Wrene97f90b2013-08-07 17:39:35 -04002737 Log.d(TAG, "converting a heads up to fullScreen");
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002738 }
Chris Wrene97f90b2013-08-07 17:39:35 -04002739 try {
Chris Wren223c66b62014-11-10 16:00:09 -05002740 EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
2741 sbn.getKey());
Chris Wrene97f90b2013-08-07 17:39:35 -04002742 notification.fullScreenIntent.send();
Selim Cinekb18a20f2015-06-04 17:08:35 +02002743 entry.entry.notifyFullScreenIntentLaunched();
Chris Wrene97f90b2013-08-07 17:39:35 -04002744 } catch (PendingIntent.CanceledException e) {
2745 }
Joe Onorato808182d2010-07-09 18:52:06 -04002746 }
2747 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002748 mHeadsUpManager.releaseAllImmediately();
Joe Onorato808182d2010-07-09 18:52:06 -04002749 }
2750
Jim Miller07e03842016-06-22 15:18:13 -07002751 /**
2752 * Called for system navigation gestures. First action opens the panel, second opens
2753 * settings. Down action closes the entire panel.
2754 */
2755 @Override
2756 public void handleSystemNavigationKey(int key) {
2757 if (SPEW) Log.d(TAG, "handleSystemNavigationKey: " + key);
Jim Miller1c21fc52016-08-02 16:12:58 -07002758 if (!panelsEnabled() || !mKeyguardMonitor.isDeviceInteractive()
Jim Miller69c12412016-10-06 19:11:03 -07002759 || mKeyguardMonitor.isShowing() && !mKeyguardMonitor.isOccluded()) {
Jim Miller07e03842016-06-22 15:18:13 -07002760 return;
2761 }
2762
2763 // Panels are not available in setup
2764 if (!mUserSetup) return;
2765
2766 if (KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP == key) {
Doris Ling3c00afb2016-07-19 17:04:21 -07002767 MetricsLogger.action(mContext, MetricsEvent.ACTION_SYSTEM_NAVIGATION_KEY_UP);
Jim Miller07e03842016-06-22 15:18:13 -07002768 mNotificationPanel.collapse(false /* delayed */, 1.0f /* speedUpFactor */);
2769 } else if (KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN == key) {
Doris Ling3c00afb2016-07-19 17:04:21 -07002770 MetricsLogger.action(mContext, MetricsEvent.ACTION_SYSTEM_NAVIGATION_KEY_DOWN);
Jim Miller07e03842016-06-22 15:18:13 -07002771 if (mNotificationPanel.isFullyCollapsed()) {
2772 mNotificationPanel.expand(true /* animate */);
Doris Ling3c00afb2016-07-19 17:04:21 -07002773 MetricsLogger.count(mContext, NotificationPanelView.COUNTER_PANEL_OPEN, 1);
Jim Miller07e03842016-06-22 15:18:13 -07002774 } else if (!mNotificationPanel.isInSettings() && !mNotificationPanel.isExpanding()){
2775 mNotificationPanel.flingSettings(0 /* velocity */, true /* expand */);
Doris Ling3c00afb2016-07-19 17:04:21 -07002776 MetricsLogger.count(mContext, NotificationPanelView.COUNTER_PANEL_OPEN_QS, 1);
Jim Miller07e03842016-06-22 15:18:13 -07002777 }
2778 }
2779
2780 }
2781
John Spurlock97642182013-07-29 17:58:39 -04002782 boolean panelsEnabled() {
Adrian Roos21d2a252015-06-01 13:59:59 -07002783 return (mDisabled1 & StatusBarManager.DISABLE_EXPAND) == 0 && !ONLY_CORE_APPS;
John Spurlock97642182013-07-29 17:58:39 -04002784 }
2785
Jorim Jaggifa505a72014-04-28 20:04:11 +02002786 void makeExpandedVisible(boolean force) {
John Spurlockcd686b52013-06-05 10:13:46 -04002787 if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
Jorim Jaggifa505a72014-04-28 20:04:11 +02002788 if (!force && (mExpandedVisible || !panelsEnabled())) {
Joe Onorato808182d2010-07-09 18:52:06 -04002789 return;
2790 }
Jim Millera073e572012-05-23 17:03:27 -07002791
Joe Onorato808182d2010-07-09 18:52:06 -04002792 mExpandedVisible = true;
Joe Onorato808182d2010-07-09 18:52:06 -04002793
Daniel Sandlera310af82012-04-24 01:20:13 -04002794 // Expand the window to encompass the full screen in anticipation of the drag.
2795 // 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 -07002796 mStatusBarWindowManager.setPanelVisible(true);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002797
2798 visibilityChanged(true);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07002799 mWaitingForKeyguardExit = false;
Adrian Roos316bf542016-08-23 17:53:07 +02002800 recomputeDisableFlags(!force /* animate */);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002801 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2802 }
2803
Daniel Sandler11cf1782012-09-27 14:03:08 -04002804 public void animateCollapsePanels() {
2805 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07002806 }
2807
John Spurlockaf8d6c42014-05-07 17:49:08 -04002808 private final Runnable mAnimateCollapsePanels = new Runnable() {
2809 @Override
2810 public void run() {
2811 animateCollapsePanels();
2812 }
2813 };
2814
2815 public void postAnimateCollapsePanels() {
2816 mHandler.post(mAnimateCollapsePanels);
2817 }
2818
Jason Monkba2318e2015-12-08 09:04:23 -05002819 public void postAnimateOpenPanels() {
2820 mHandler.sendEmptyMessage(MSG_OPEN_SETTINGS_PANEL);
2821 }
2822
Jim Miller07e03842016-06-22 15:18:13 -07002823 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04002824 public void animateCollapsePanels(int flags) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002825 animateCollapsePanels(flags, false /* force */, false /* delayed */,
2826 1.0f /* speedUpFactor */);
Jorim Jaggi34250762014-07-03 23:51:19 +02002827 }
2828
Jim Miller07e03842016-06-22 15:18:13 -07002829 @Override
Jorim Jaggi34250762014-07-03 23:51:19 +02002830 public void animateCollapsePanels(int flags, boolean force) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002831 animateCollapsePanels(flags, force, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002832 }
2833
Jim Miller07e03842016-06-22 15:18:13 -07002834 @Override
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002835 public void animateCollapsePanels(int flags, boolean force, boolean delayed) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002836 animateCollapsePanels(flags, force, delayed, 1.0f /* speedUpFactor */);
2837 }
2838
2839 public void animateCollapsePanels(int flags, boolean force, boolean delayed,
2840 float speedUpFactor) {
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07002841 if (!force && mState != StatusBarState.SHADE) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002842 runPostCollapseRunnables();
Jorim Jaggic1cf1ae2014-05-02 21:19:17 +02002843 return;
2844 }
Joe Onorato808182d2010-07-09 18:52:06 -04002845 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04002846 Log.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04002847 + " mExpandedVisible=" + mExpandedVisible
Jim Miller9a720f52012-05-30 03:19:43 -07002848 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04002849 }
2850
Jim Miller9a720f52012-05-30 03:19:43 -07002851 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Winson Chungcdcd4872014-08-05 18:00:13 -07002852 if (!mHandler.hasMessages(MSG_HIDE_RECENT_APPS)) {
2853 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
2854 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
2855 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07002856 }
Jim Miller9a720f52012-05-30 03:19:43 -07002857
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002858 if (mStatusBarWindow != null) {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002859 // release focus immediately to kick off focus change transition
2860 mStatusBarWindowManager.setStatusBarFocusable(false);
2861
John Spurlockab847cf2014-01-15 14:13:59 -05002862 mStatusBarWindow.cancelExpandHelper();
Xiaohui Chen9f967112016-01-07 14:14:06 -08002863 mStatusBarView.collapsePanel(true /* animate */, delayed, speedUpFactor);
John Spurlockab847cf2014-01-15 14:13:59 -05002864 }
Joe Onorato808182d2010-07-09 18:52:06 -04002865 }
2866
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002867 private void runPostCollapseRunnables() {
Selim Cinekae77f8e2015-07-07 18:43:59 -07002868 ArrayList<Runnable> clonedList = new ArrayList<>(mPostCollapseRunnables);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002869 mPostCollapseRunnables.clear();
Selim Cinekae77f8e2015-07-07 18:43:59 -07002870 int size = clonedList.size();
2871 for (int i = 0; i < size; i++) {
2872 clonedList.get(i).run();
2873 }
2874
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002875 }
2876
Daniel Sandler08d05e32012-08-08 16:39:54 -04002877 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04002878 public void animateExpandNotificationsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04002879 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002880 if (!panelsEnabled()) {
Joe Onorato808182d2010-07-09 18:52:06 -04002881 return ;
2882 }
Joe Onorato808182d2010-07-09 18:52:06 -04002883
Oren Blasberg8d3fea12015-07-10 14:21:44 -07002884 mNotificationPanel.expand(true /* animate */);
Joe Onorato808182d2010-07-09 18:52:06 -04002885
2886 if (false) postStartTracing();
2887 }
2888
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002889 @Override
Jason Monka9927322015-12-13 16:22:37 -05002890 public void animateExpandSettingsPanel(String subPanel) {
John Spurlockcd686b52013-06-05 10:13:46 -04002891 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002892 if (!panelsEnabled()) {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002893 return;
2894 }
2895
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05002896 // Settings are not available in setup
2897 if (!mUserSetup) return;
2898
Jason Monka9927322015-12-13 16:22:37 -05002899
2900 if (subPanel != null) {
2901 mQSPanel.openDetails(subPanel);
2902 }
Jason Monk3c68ca22015-01-30 11:30:29 -05002903 mNotificationPanel.expandWithQs();
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002904
2905 if (false) postStartTracing();
2906 }
2907
2908 public void animateCollapseQuickSettings() {
Jorim Jaggi449981b2014-10-03 14:24:55 -07002909 if (mState == StatusBarState.SHADE) {
Xiaohui Chen9f967112016-01-07 14:14:06 -08002910 mStatusBarView.collapsePanel(true, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi449981b2014-10-03 14:24:55 -07002911 }
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002912 }
2913
Daniel Sandler08d05e32012-08-08 16:39:54 -04002914 void makeExpandedInvisible() {
John Spurlockcd686b52013-06-05 10:13:46 -04002915 if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04002916 + " mExpandedVisible=" + mExpandedVisible);
2917
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002918 if (!mExpandedVisible || mStatusBarWindow == null) {
Joe Onorato808182d2010-07-09 18:52:06 -04002919 return;
2920 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002921
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04002922 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
Xiaohui Chen9f967112016-01-07 14:14:06 -08002923 mStatusBarView.collapsePanel(/*animate=*/ false, false /* delayed*/,
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002924 1.0f /* speedUpFactor */);
Daniel Sandlered930e52012-07-03 14:31:22 -04002925
Jorim Jaggid7daab72014-05-06 22:22:20 +02002926 mNotificationPanel.closeQs();
Daniel Sandler040c2e42012-10-17 00:56:33 -04002927
Joe Onorato808182d2010-07-09 18:52:06 -04002928 mExpandedVisible = false;
2929 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04002930
2931 // Shrink the window to the size of the status bar only
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002932 mStatusBarWindowManager.setPanelVisible(false);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002933 mStatusBarWindowManager.setForceStatusBarVisible(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002934
Daniel Sandler469e96e2012-05-04 15:56:19 -04002935 // Close any "App info" popups that might have snuck on-screen
2936 dismissPopups();
2937
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002938 runPostCollapseRunnables();
John Spurlockcfc359a2013-09-05 10:42:03 -04002939 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
Adrian Roosf37fce52016-12-13 15:12:02 -08002940 showBouncerIfKeyguard();
Adrian Roos316bf542016-08-23 17:53:07 +02002941 recomputeDisableFlags(true /* animate */);
Jorim Jaggi786afcb2014-09-25 02:41:29 +02002942
2943 // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in
2944 // the bouncer appear animation.
2945 if (!mStatusBarKeyguardViewManager.isShowing()) {
2946 WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
2947 }
Joe Onorato808182d2010-07-09 18:52:06 -04002948 }
2949
Daniel Sandlerb17a7262012-10-05 14:32:50 -04002950 public boolean interceptTouchEvent(MotionEvent event) {
Chris Wren64161cc2012-12-17 16:49:30 -05002951 if (DEBUG_GESTURES) {
2952 if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
2953 EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002954 event.getActionMasked(), (int) event.getX(), (int) event.getY(),
2955 mDisabled1, mDisabled2);
Chris Wren64161cc2012-12-17 16:49:30 -05002956 }
2957
2958 }
2959
Joe Onorato808182d2010-07-09 18:52:06 -04002960 if (SPEW) {
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002961 Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled1="
2962 + mDisabled1 + " mDisabled2=" + mDisabled2 + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002963 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002964 if (event.getAction() != MotionEvent.ACTION_MOVE) {
John Spurlockcd686b52013-06-05 10:13:46 -04002965 Log.d(TAG, String.format(
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002966 "panel: %s at (%f, %f) mDisabled1=0x%08x mDisabled2=0x%08x",
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002967 MotionEvent.actionToString(event.getAction()),
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002968 event.getRawX(), event.getRawY(), mDisabled1, mDisabled2));
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002969 }
Joe Onorato808182d2010-07-09 18:52:06 -04002970 }
2971
Daniel Sandler151f00d2012-10-02 22:33:08 -04002972 if (DEBUG_GESTURES) {
2973 mGestureRec.add(event);
2974 }
Daniel Sandler33805342012-07-23 15:45:12 -04002975
John Spurlock686820a2013-09-03 14:44:16 -04002976 if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
John Spurlock5fee8362013-09-12 10:34:33 -04002977 final boolean upOrCancel =
2978 event.getAction() == MotionEvent.ACTION_UP ||
2979 event.getAction() == MotionEvent.ACTION_CANCEL;
2980 if (upOrCancel && !mExpandedVisible) {
2981 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
2982 } else {
2983 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2984 }
John Spurlock686820a2013-09-03 14:44:16 -04002985 }
Joe Onorato808182d2010-07-09 18:52:06 -04002986 return false;
2987 }
2988
Daniel Sandler08d05e32012-08-08 16:39:54 -04002989 public GestureRecorder getGestureRecorder() {
2990 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07002991 }
2992
John Spurlock56d007b2013-10-28 18:40:56 -04002993 private void setNavigationIconHints(int hints) {
Daniel Sandler328310c2011-09-23 15:56:52 -04002994 if (hints == mNavigationIconHints) return;
2995
2996 mNavigationIconHints = hints;
2997
2998 if (mNavigationBarView != null) {
2999 mNavigationBarView.setNavigationIconHints(hints);
3000 }
John Spurlockd4e65752013-08-28 14:17:09 -04003001 checkBarModes();
Daniel Sandler328310c2011-09-23 15:56:52 -04003002 }
3003
3004 @Override // CommandQueue
John Spurlock97642182013-07-29 17:58:39 -04003005 public void setWindowState(int window, int state) {
John Spurlockd4e65752013-08-28 14:17:09 -04003006 boolean showing = state == WINDOW_STATE_SHOWING;
John Spurlock97642182013-07-29 17:58:39 -04003007 if (mStatusBarWindow != null
3008 && window == StatusBarManager.WINDOW_STATUS_BAR
3009 && mStatusBarWindowState != state) {
3010 mStatusBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04003011 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
Jorim Jaggi449981b2014-10-03 14:24:55 -07003012 if (!showing && mState == StatusBarState.SHADE) {
Xiaohui Chen9f967112016-01-07 14:14:06 -08003013 mStatusBarView.collapsePanel(false /* animate */, false /* delayed */,
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07003014 1.0f /* speedUpFactor */);
John Spurlock97642182013-07-29 17:58:39 -04003015 }
3016 }
3017 if (mNavigationBarView != null
3018 && window == StatusBarManager.WINDOW_NAVIGATION_BAR
3019 && mNavigationBarWindowState != state) {
3020 mNavigationBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04003021 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
John Spurlock97642182013-07-29 17:58:39 -04003022 }
3023 }
3024
John Spurlock97642182013-07-29 17:58:39 -04003025 @Override // CommandQueue
John Spurlockcad57682014-07-26 17:09:56 -04003026 public void buzzBeepBlinked() {
3027 if (mDozeServiceHost != null) {
3028 mDozeServiceHost.fireBuzzBeepBlinked();
3029 }
3030 }
3031
John Spurlockcb566aa2014-08-03 22:58:28 -04003032 @Override
3033 public void notificationLightOff() {
3034 if (mDozeServiceHost != null) {
3035 mDozeServiceHost.fireNotificationLight(false);
3036 }
3037 }
3038
3039 @Override
3040 public void notificationLightPulse(int argb, int onMillis, int offMillis) {
3041 if (mDozeServiceHost != null) {
3042 mDozeServiceHost.fireNotificationLight(true);
3043 }
3044 }
3045
John Spurlockcad57682014-07-26 17:09:56 -04003046 @Override // CommandQueue
Jorim Jaggi86905582016-02-09 21:36:09 -08003047 public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
3048 int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07003049 final int oldVal = mSystemUiVisibility;
3050 final int newVal = (oldVal&~mask) | (vis&mask);
3051 final int diff = newVal ^ oldVal;
John Spurlockcd686b52013-06-05 10:13:46 -04003052 if (DEBUG) Log.d(TAG, String.format(
John Spurlockdcf4f212013-05-21 17:19:53 -04003053 "setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",
3054 Integer.toHexString(vis), Integer.toHexString(mask),
3055 Integer.toHexString(oldVal), Integer.toHexString(newVal),
3056 Integer.toHexString(diff)));
Jorim Jaggi86905582016-02-09 21:36:09 -08003057 boolean sbModeChanged = false;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04003058 if (diff != 0) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07003059 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04003060
John Spurlocke1f366f2013-08-05 12:22:40 -04003061 // update low profile
3062 if ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
John Spurlock7edfbca2013-09-14 11:58:55 -04003063 setAreThereNotifications();
Daniel Sandler60ee2562011-07-22 12:34:33 -04003064 }
3065
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07003066 // ready to unhide
3067 if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
3068 mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
3069 mNoAnimationOnNextBarModeChange = true;
3070 }
3071
John Spurlocke1f366f2013-08-05 12:22:40 -04003072 // update status bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04003073 final int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
Jorim Jaggi4fa78922015-11-30 17:13:56 -08003074 View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT,
3075 View.STATUS_BAR_TRANSPARENT);
John Spurlocke1f366f2013-08-05 12:22:40 -04003076
3077 // update navigation bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04003078 final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
John Spurlockf6b63972013-08-27 16:08:28 -04003079 oldVal, newVal, mNavigationBarView.getBarTransitions(),
Jorim Jaggi4fa78922015-11-30 17:13:56 -08003080 View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,
3081 View.NAVIGATION_BAR_TRANSPARENT);
Jorim Jaggi86905582016-02-09 21:36:09 -08003082 sbModeChanged = sbMode != -1;
John Spurlockd4e65752013-08-28 14:17:09 -04003083 final boolean nbModeChanged = nbMode != -1;
3084 boolean checkBarModes = false;
3085 if (sbModeChanged && sbMode != mStatusBarMode) {
3086 mStatusBarMode = sbMode;
3087 checkBarModes = true;
3088 }
3089 if (nbModeChanged && nbMode != mNavigationBarMode) {
3090 mNavigationBarMode = nbMode;
3091 checkBarModes = true;
3092 }
3093 if (checkBarModes) {
3094 checkBarModes();
3095 }
3096 if (sbModeChanged || nbModeChanged) {
John Spurlocke1f366f2013-08-05 12:22:40 -04003097 // update transient bar autohide
John Spurlockc6d1c602014-01-17 15:22:06 -05003098 if (mStatusBarMode == MODE_SEMI_TRANSPARENT || mNavigationBarMode == MODE_SEMI_TRANSPARENT) {
John Spurlock32beb2c2013-03-11 10:16:47 -04003099 scheduleAutohide();
3100 } else {
John Spurlock32beb2c2013-03-11 10:16:47 -04003101 cancelAutohide();
3102 }
3103 }
John Spurlocke1f366f2013-08-05 12:22:40 -04003104
John Spurlock5b9145b2013-08-20 15:13:47 -04003105 if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
3106 mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
3107 }
3108
John Spurlocke1f366f2013-08-05 12:22:40 -04003109 // send updated sysui visibility to window manager
John Spurlock32beb2c2013-03-11 10:16:47 -04003110 notifyUiVisibilityChanged(mSystemUiVisibility);
Joe Onorato93056472010-09-10 10:30:46 -04003111 }
Jorim Jaggi86905582016-02-09 21:36:09 -08003112
3113 mLightStatusBarController.onSystemUiVisibilityChanged(fullscreenStackVis, dockedStackVis,
3114 mask, fullscreenStackBounds, dockedStackBounds, sbModeChanged, mStatusBarMode);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04003115 }
3116
John Spurlockd4e65752013-08-28 14:17:09 -04003117 private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
Jorim Jaggi4fa78922015-11-30 17:13:56 -08003118 int transientFlag, int translucentFlag, int transparentFlag) {
3119 final int oldMode = barMode(oldVis, transientFlag, translucentFlag, transparentFlag);
3120 final int newMode = barMode(newVis, transientFlag, translucentFlag, transparentFlag);
John Spurlocke1f366f2013-08-05 12:22:40 -04003121 if (oldMode == newMode) {
3122 return -1; // no mode change
3123 }
John Spurlocke1f366f2013-08-05 12:22:40 -04003124 return newMode;
3125 }
3126
Jorim Jaggi4fa78922015-11-30 17:13:56 -08003127 private int barMode(int vis, int transientFlag, int translucentFlag, int transparentFlag) {
3128 int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | transparentFlag;
John Spurlock89835dd2013-08-16 15:06:51 -04003129 return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
John Spurlockbd957402013-10-03 11:38:39 -04003130 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
Adrian Roosc0f0a742014-10-28 16:39:56 +01003131 : (vis & lightsOutTransparent) == lightsOutTransparent ? MODE_LIGHTS_OUT_TRANSPARENT
Jorim Jaggi4fa78922015-11-30 17:13:56 -08003132 : (vis & transparentFlag) != 0 ? MODE_TRANSPARENT
John Spurlock7edfbca2013-09-14 11:58:55 -04003133 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
John Spurlock3b139a92013-08-17 17:18:08 -04003134 : MODE_OPAQUE;
John Spurlocke1f366f2013-08-05 12:22:40 -04003135 }
3136
John Spurlockd4e65752013-08-28 14:17:09 -04003137 private void checkBarModes() {
John Spurlock3c875662013-08-31 15:07:25 -04003138 if (mDemoMode) return;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07003139 checkBarMode(mStatusBarMode, mStatusBarWindowState, mStatusBarView.getBarTransitions(),
3140 mNoAnimationOnNextBarModeChange);
John Spurlockd4e65752013-08-28 14:17:09 -04003141 if (mNavigationBarView != null) {
3142 checkBarMode(mNavigationBarMode,
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07003143 mNavigationBarWindowState, mNavigationBarView.getBarTransitions(),
3144 mNoAnimationOnNextBarModeChange);
John Spurlockd4e65752013-08-28 14:17:09 -04003145 }
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07003146 mNoAnimationOnNextBarModeChange = false;
John Spurlockd4e65752013-08-28 14:17:09 -04003147 }
3148
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07003149 private void checkBarMode(int mode, int windowState, BarTransitions transitions,
3150 boolean noAnimation) {
John Spurlock0ff62e02014-07-22 16:15:08 -04003151 final boolean powerSave = mBatteryController.isPowerSave();
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003152 final boolean anim = !noAnimation && mDeviceInteractive
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07003153 && windowState != WINDOW_STATE_HIDDEN && !powerSave;
John Spurlock1bb480a2014-08-02 17:12:43 -04003154 if (powerSave && getBarState() == StatusBarState.SHADE) {
John Spurlock0ff62e02014-07-22 16:15:08 -04003155 mode = MODE_WARNING;
3156 }
John Spurlockc68d5772013-10-08 11:47:58 -04003157 transitions.transitionTo(mode, anim);
John Spurlockd4e65752013-08-28 14:17:09 -04003158 }
3159
John Spurlock42197262013-10-21 09:32:25 -04003160 private void finishBarAnimations() {
3161 mStatusBarView.getBarTransitions().finishAnimations();
3162 if (mNavigationBarView != null) {
3163 mNavigationBarView.getBarTransitions().finishAnimations();
3164 }
3165 }
3166
John Spurlockd4e65752013-08-28 14:17:09 -04003167 private final Runnable mCheckBarModes = new Runnable() {
John Spurlock5b9145b2013-08-20 15:13:47 -04003168 @Override
3169 public void run() {
John Spurlockd4e65752013-08-28 14:17:09 -04003170 checkBarModes();
John Spurlock0ff62e02014-07-22 16:15:08 -04003171 }
3172 };
John Spurlock5b9145b2013-08-20 15:13:47 -04003173
John Spurlockad3e6cb2013-04-30 08:47:43 -04003174 @Override
John Spurlockcfc359a2013-09-05 10:42:03 -04003175 public void setInteracting(int barWindow, boolean interacting) {
John Spurlock7fbf5732014-11-18 11:40:22 -05003176 final boolean changing = ((mInteractingWindows & barWindow) != 0) != interacting;
John Spurlockcfc359a2013-09-05 10:42:03 -04003177 mInteractingWindows = interacting
3178 ? (mInteractingWindows | barWindow)
3179 : (mInteractingWindows & ~barWindow);
3180 if (mInteractingWindows != 0) {
John Spurlockd4e65752013-08-28 14:17:09 -04003181 suspendAutohide();
3182 } else {
3183 resumeSuspendedAutohide();
3184 }
John Spurlock7fbf5732014-11-18 11:40:22 -05003185 // manually dismiss the volume panel when interacting with the nav bar
3186 if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) {
John Spurlockb349af572015-04-29 12:24:19 -04003187 dismissVolumeDialog();
John Spurlock7fbf5732014-11-18 11:40:22 -05003188 }
John Spurlockd4e65752013-08-28 14:17:09 -04003189 checkBarModes();
3190 }
3191
John Spurlockb349af572015-04-29 12:24:19 -04003192 private void dismissVolumeDialog() {
3193 if (mVolumeComponent != null) {
3194 mVolumeComponent.dismissNow();
3195 }
3196 }
3197
John Spurlockd4e65752013-08-28 14:17:09 -04003198 private void resumeSuspendedAutohide() {
John Spurlockad3e6cb2013-04-30 08:47:43 -04003199 if (mAutohideSuspended) {
3200 scheduleAutohide();
John Spurlockd4e65752013-08-28 14:17:09 -04003201 mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher
John Spurlock3b139a92013-08-17 17:18:08 -04003202 }
3203 }
3204
John Spurlockd4e65752013-08-28 14:17:09 -04003205 private void suspendAutohide() {
John Spurlock32beb2c2013-03-11 10:16:47 -04003206 mHandler.removeCallbacks(mAutohide);
John Spurlockd4e65752013-08-28 14:17:09 -04003207 mHandler.removeCallbacks(mCheckBarModes);
John Spurlock5b9145b2013-08-20 15:13:47 -04003208 mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
John Spurlock32beb2c2013-03-11 10:16:47 -04003209 }
3210
3211 private void cancelAutohide() {
3212 mAutohideSuspended = false;
3213 mHandler.removeCallbacks(mAutohide);
3214 }
3215
3216 private void scheduleAutohide() {
3217 cancelAutohide();
3218 mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
3219 }
3220
John Spurlock9deaa282013-07-25 13:03:47 -04003221 private void checkUserAutohide(View v, MotionEvent event) {
John Spurlocke1f366f2013-08-05 12:22:40 -04003222 if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
John Spurlock9deaa282013-07-25 13:03:47 -04003223 && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
3224 && event.getX() == 0 && event.getY() == 0 // a touch outside both bars
Adrian Roos5e476452016-05-27 12:07:33 -07003225 && !mRemoteInputController.isRemoteInputActive()) { // not due to typing in IME
John Spurlock9deaa282013-07-25 13:03:47 -04003226 userAutohide();
3227 }
3228 }
3229
Adrian Roos6d53de62016-12-19 16:17:50 -08003230 private void checkRemoteInputOutside(MotionEvent event) {
3231 if (event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
3232 && event.getX() == 0 && event.getY() == 0 // a touch outside both bars
3233 && mRemoteInputController.isRemoteInputActive()) {
3234 mRemoteInputController.closeRemoteInputs();
3235 }
3236 }
3237
John Spurlock9deaa282013-07-25 13:03:47 -04003238 private void userAutohide() {
3239 cancelAutohide();
John Spurlock5b9145b2013-08-20 15:13:47 -04003240 mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
John Spurlock9deaa282013-07-25 13:03:47 -04003241 }
3242
Daniel Sandlerd7e96862012-04-26 01:10:29 -04003243 private boolean areLightsOn() {
3244 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
3245 }
Jim Millera073e572012-05-23 17:03:27 -07003246
Daniel Sandler60ee2562011-07-22 12:34:33 -04003247 public void setLightsOn(boolean on) {
3248 Log.v(TAG, "setLightsOn(" + on + ")");
3249 if (on) {
Jorim Jaggi86905582016-02-09 21:36:09 -08003250 setSystemUiVisibility(0, 0, 0, View.SYSTEM_UI_FLAG_LOW_PROFILE,
3251 mLastFullscreenStackBounds, mLastDockedStackBounds);
Daniel Sandler60ee2562011-07-22 12:34:33 -04003252 } else {
Jorim Jaggi86905582016-02-09 21:36:09 -08003253 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, 0, 0,
3254 View.SYSTEM_UI_FLAG_LOW_PROFILE, mLastFullscreenStackBounds,
3255 mLastDockedStackBounds);
Daniel Sandler60ee2562011-07-22 12:34:33 -04003256 }
3257 }
3258
John Spurlock32beb2c2013-03-11 10:16:47 -04003259 private void notifyUiVisibilityChanged(int vis) {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04003260 try {
Adrian Roos389beec2015-05-12 13:33:25 -07003261 if (mLastDispatchedSystemUiVisibility != vis) {
3262 mWindowManagerService.statusBarVisibilityChanged(vis);
3263 mLastDispatchedSystemUiVisibility = vis;
3264 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04003265 } catch (RemoteException ex) {
3266 }
Joe Onorato93056472010-09-10 10:30:46 -04003267 }
3268
Jim Miller07e03842016-06-22 15:18:13 -07003269 @Override
Daniel Sandler5c8da942011-06-28 00:29:04 -04003270 public void topAppWindowChanged(boolean showMenu) {
Chris Wren8a1638f2016-05-02 16:19:14 -04003271 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04003272 Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
Daniel Sandler5c8da942011-06-28 00:29:04 -04003273 }
3274 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04003275 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04003276 }
3277
3278 // See above re: lights-out policy for legacy apps.
3279 if (showMenu) setLightsOn(true);
3280 }
3281
Daniel Sandler328310c2011-09-23 15:56:52 -04003282 @Override
Jason Monkb605fec2014-05-02 17:04:10 -04003283 public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
3284 boolean showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04003285 boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
3286 int flags = mNavigationIconHints;
3287 if ((backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS) || imeShown) {
3288 flags |= NAVIGATION_HINT_BACK_ALT;
3289 } else {
3290 flags &= ~NAVIGATION_HINT_BACK_ALT;
3291 }
Jason Monkb605fec2014-05-02 17:04:10 -04003292 if (showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04003293 flags |= NAVIGATION_HINT_IME_SHOWN;
3294 } else {
3295 flags &= ~NAVIGATION_HINT_IME_SHOWN;
3296 }
Daniel Sandler328310c2011-09-23 15:56:52 -04003297
Jason Monkf1ff2092014-04-29 16:50:53 -04003298 setNavigationIconHints(flags);
Daniel Sandler328310c2011-09-23 15:56:52 -04003299 }
3300
Daniel Sandler48852952011-12-01 14:34:23 -05003301 public static String viewInfo(View v) {
3302 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
3303 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04003304 }
3305
Jim Miller07e03842016-06-22 15:18:13 -07003306 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04003307 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04003308 synchronized (mQueueLock) {
3309 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04003310 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04003311 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04003312 pw.println(" mTracking=" + mTracking);
Daniel Sandler36412a72011-08-04 09:35:13 -04003313 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Selim Cinekb6d85eb2014-03-28 20:21:01 +01003314 pw.println(" mStackScroller: " + viewInfo(mStackScroller));
Selim Cinekb6d85eb2014-03-28 20:21:01 +01003315 pw.println(" mStackScroller: " + viewInfo(mStackScroller)
3316 + " scroll " + mStackScroller.getScrollX()
3317 + "," + mStackScroller.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04003318 }
Joe Onorato808182d2010-07-09 18:52:06 -04003319
John Spurlockcfc359a2013-09-05 10:42:03 -04003320 pw.print(" mInteractingWindows="); pw.println(mInteractingWindows);
John Spurlock0ec64c62013-08-26 15:37:58 -04003321 pw.print(" mStatusBarWindowState=");
3322 pw.println(windowStateToString(mStatusBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04003323 pw.print(" mStatusBarMode=");
3324 pw.println(BarTransitions.modeToString(mStatusBarMode));
John Spurlockbf370992014-06-17 13:58:31 -04003325 pw.print(" mDozing="); pw.println(mDozing);
John Spurlocke677d712014-02-13 12:52:19 -05003326 pw.print(" mZenMode=");
3327 pw.println(Settings.Global.zenModeToString(mZenMode));
Chris Wren3b6745b2014-03-07 14:34:35 -05003328 pw.print(" mUseHeadsUp=");
3329 pw.println(mUseHeadsUp);
John Spurlock0ec64c62013-08-26 15:37:58 -04003330 dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
3331 if (mNavigationBarView != null) {
3332 pw.print(" mNavigationBarWindowState=");
3333 pw.println(windowStateToString(mNavigationBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04003334 pw.print(" mNavigationBarMode=");
3335 pw.println(BarTransitions.modeToString(mNavigationBarMode));
John Spurlock0ec64c62013-08-26 15:37:58 -04003336 dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
3337 }
3338
Daniel Sandler48852952011-12-01 14:34:23 -05003339 pw.print(" mNavigationBarView=");
3340 if (mNavigationBarView == null) {
3341 pw.println("null");
3342 } else {
3343 mNavigationBarView.dump(fd, pw, args);
3344 }
3345
Dan Sandler16128f42014-05-21 12:48:22 -04003346 pw.print(" mMediaSessionManager=");
3347 pw.println(mMediaSessionManager);
3348 pw.print(" mMediaNotificationKey=");
3349 pw.println(mMediaNotificationKey);
3350 pw.print(" mMediaController=");
3351 pw.print(mMediaController);
3352 if (mMediaController != null) {
3353 pw.print(" state=" + mMediaController.getPlaybackState());
3354 }
3355 pw.println();
3356 pw.print(" mMediaMetadata=");
3357 pw.print(mMediaMetadata);
3358 if (mMediaMetadata != null) {
RoboErik75847b92014-07-29 13:10:17 -07003359 pw.print(" title=" + mMediaMetadata.getText(MediaMetadata.METADATA_KEY_TITLE));
Dan Sandler16128f42014-05-21 12:48:22 -04003360 }
3361 pw.println();
3362
Daniel Sandler37a38aa2013-02-13 17:15:57 -05003363 pw.println(" Panels: ");
3364 if (mNotificationPanel != null) {
3365 pw.println(" mNotificationPanel=" +
3366 mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""));
3367 pw.print (" ");
3368 mNotificationPanel.dump(fd, pw, args);
3369 }
Daniel Sandler37a38aa2013-02-13 17:15:57 -05003370
John Spurlock813552c2014-09-19 08:30:21 -04003371 DozeLog.dump(pw);
3372
Daniel Sandler7579bca2011-08-18 15:47:26 -04003373 if (DUMPTRUCK) {
3374 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02003375 mNotificationData.dump(pw, " ");
Daniel Sandler7579bca2011-08-18 15:47:26 -04003376 }
3377
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003378 mIconController.dump(pw);
Jim Miller5e6af442011-12-02 18:24:26 -08003379
Daniel Sandler89d97132011-09-08 15:31:57 -04003380 if (false) {
3381 pw.println("see the logcat for a dump of the views we have created.");
3382 // must happen on ui thread
3383 mHandler.post(new Runnable() {
Jim Miller07e03842016-06-22 15:18:13 -07003384 @Override
Daniel Sandler89d97132011-09-08 15:31:57 -04003385 public void run() {
3386 mStatusBarView.getLocationOnScreen(mAbsPos);
John Spurlockcd686b52013-06-05 10:13:46 -04003387 Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
Daniel Sandler89d97132011-09-08 15:31:57 -04003388 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04003389 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04003390 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04003391 }
3392 });
3393 }
Joe Onorato808182d2010-07-09 18:52:06 -04003394 }
Daniel Sandler89d97132011-09-08 15:31:57 -04003395
Daniel Sandler151f00d2012-10-02 22:33:08 -04003396 if (DEBUG_GESTURES) {
3397 pw.print(" status bar gestures: ");
3398 mGestureRec.dump(fd, pw, args);
3399 }
Selim Cinek7025f262015-07-13 16:22:48 -07003400 if (mStatusBarWindowManager != null) {
3401 mStatusBarWindowManager.dump(fd, pw, args);
3402 }
John Spurlock486b78e2014-07-07 08:37:56 -04003403 if (mNetworkController != null) {
3404 mNetworkController.dump(fd, pw, args);
3405 }
3406 if (mBluetoothController != null) {
3407 mBluetoothController.dump(fd, pw, args);
3408 }
Jason Monkdd5bdc62015-07-20 12:18:38 -04003409 if (mHotspotController != null) {
3410 mHotspotController.dump(fd, pw, args);
3411 }
John Spurlock1e6eb172014-07-13 11:59:50 -04003412 if (mCastController != null) {
3413 mCastController.dump(fd, pw, args);
3414 }
Adrian Roos00a0b1f2014-07-16 16:44:49 +02003415 if (mUserSwitcherController != null) {
3416 mUserSwitcherController.dump(fd, pw, args);
3417 }
John Spurlock0ff62e02014-07-22 16:15:08 -04003418 if (mBatteryController != null) {
3419 mBatteryController.dump(fd, pw, args);
3420 }
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02003421 if (mNextAlarmController != null) {
3422 mNextAlarmController.dump(fd, pw, args);
3423 }
Jason Monk3d5f5512014-07-25 11:17:28 -04003424 if (mSecurityController != null) {
3425 mSecurityController.dump(fd, pw, args);
3426 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07003427 if (mHeadsUpManager != null) {
3428 mHeadsUpManager.dump(fd, pw, args);
Chris Wren428c6b62014-12-05 16:07:06 -05003429 } else {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07003430 pw.println(" mHeadsUpManager: null");
Chris Wren428c6b62014-12-05 16:07:06 -05003431 }
Selim Cinek52941c52016-05-07 18:29:32 -04003432 if (mGroupManager != null) {
3433 mGroupManager.dump(fd, pw, args);
3434 } else {
3435 pw.println(" mGroupManager: null");
3436 }
Jason Monkab525272015-07-13 17:02:49 -04003437 if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
3438 KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
3439 }
Jason Monkad32c552016-10-04 14:50:11 -04003440 if (mFlashlightController != null) {
3441 mFlashlightController.dump(fd, pw, args);
3442 }
Chris Wren428c6b62014-12-05 16:07:06 -05003443
Adrian Roos401caae2016-03-04 13:35:21 -08003444 FalsingManager.getInstance(mContext).dump(pw);
3445 FalsingLog.dump(pw);
3446
John Spurlock7bbb9f62014-10-21 12:15:28 -04003447 pw.println("SharedPreferences:");
Andrew Flynn82862572015-04-01 14:22:37 -04003448 for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
John Spurlock7bbb9f62014-10-21 12:15:28 -04003449 pw.print(" "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
3450 }
Joe Onorato808182d2010-07-09 18:52:06 -04003451 }
3452
John Spurlock0ec64c62013-08-26 15:37:58 -04003453 private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
3454 pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
3455 pw.println(BarTransitions.modeToString(transitions.getMode()));
3456 }
3457
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05003458 @Override
3459 public void createAndAddWindows() {
3460 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04003461 }
Jim Millere898ac52012-04-06 17:10:57 -07003462
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05003463 private void addStatusBarWindow() {
Daniel Sandlera310af82012-04-24 01:20:13 -04003464 makeStatusBarView();
Jorim Jaggi5cf17872014-03-26 18:31:48 +01003465 mStatusBarWindowManager = new StatusBarWindowManager(mContext);
Adrian Roos1c0ca502015-10-07 12:20:42 -07003466 mRemoteInputController = new RemoteInputController(mStatusBarWindowManager,
3467 mHeadsUpManager);
Jorim Jaggi5cf17872014-03-26 18:31:48 +01003468 mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
Joe Onorato808182d2010-07-09 18:52:06 -04003469 }
3470
Daniel Sandler747a9e92012-08-10 16:39:19 -04003471 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07003472 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04003473 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler7e8ae502013-10-10 23:38:19 -04003474 mDisplay.getSize(mCurrentDisplaySize);
Daniel Sandler151f00d2012-10-02 22:33:08 -04003475 if (DEBUG_GESTURES) {
John Spurlock209bede2013-07-17 12:23:27 -04003476 mGestureRec.tag("display",
Daniel Sandler151f00d2012-10-02 22:33:08 -04003477 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
3478 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07003479 }
3480
Christoph Studerb0183992014-12-22 21:02:26 +01003481 float getDisplayDensity() {
3482 return mDisplayMetrics.density;
3483 }
3484
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003485 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
Jorim Jaggid9449862015-05-29 14:49:08 -07003486 boolean dismissShade) {
3487 startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, null /* callback */);
3488 }
3489
3490 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
3491 final boolean dismissShade, final Callback callback) {
Daniel Sandler3679bf52012-10-16 21:30:28 -04003492 if (onlyProvisioned && !isDeviceProvisioned()) return;
Adrian Roos4314f6d2014-05-28 14:10:27 +02003493
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02003494 final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
3495 mContext, intent, mCurrentUserId);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02003496 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Selim Cineke70d6532015-04-24 16:46:13 -07003497 Runnable runnable = new Runnable() {
Jim Miller07e03842016-06-22 15:18:13 -07003498 @Override
Selim Cineke70d6532015-04-24 16:46:13 -07003499 public void run() {
Jorim Jaggib835dd72015-06-08 12:28:42 -07003500 mAssistManager.hideAssist();
Selim Cineke70d6532015-04-24 16:46:13 -07003501 intent.setFlags(
3502 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Jorim Jaggid9449862015-05-29 14:49:08 -07003503 int result = ActivityManager.START_CANCELED;
Robert Carrfd10cd12016-06-29 16:41:50 -07003504 ActivityOptions options = new ActivityOptions(getActivityOptions());
3505 if (intent == KeyguardBottomAreaView.INSECURE_CAMERA_INTENT) {
3506 // Normally an activity will set it's requested rotation
3507 // animation on its window. However when launching an activity
3508 // causes the orientation to change this is too late. In these cases
3509 // the default animation is used. This doesn't look good for
3510 // the camera (as it rotates the camera contents out of sync
3511 // with physical reality). So, we ask the WindowManager to
3512 // force the crossfade animation if an orientation change
3513 // happens to occur during the launch.
3514 options.setRotationAnimationHint(
Robert Carr57d9fbd2016-08-15 12:00:35 -07003515 WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
Robert Carrfd10cd12016-06-29 16:41:50 -07003516 }
Jorim Jaggid9449862015-05-29 14:49:08 -07003517 try {
3518 result = ActivityManagerNative.getDefault().startActivityAsUser(
3519 null, mContext.getBasePackageName(),
3520 intent,
3521 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Jorim Jaggie6e108e2016-03-28 13:38:45 -07003522 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
Robert Carrfd10cd12016-06-29 16:41:50 -07003523 options.toBundle(), UserHandle.CURRENT.getIdentifier());
Jorim Jaggid9449862015-05-29 14:49:08 -07003524 } catch (RemoteException e) {
3525 Log.w(TAG, "Unable to start activity", e);
3526 }
Selim Cineke70d6532015-04-24 16:46:13 -07003527 overrideActivityPendingAppTransition(
3528 keyguardShowing && !afterKeyguardGone);
Jorim Jaggid9449862015-05-29 14:49:08 -07003529 if (callback != null) {
3530 callback.onActivityStarted(result);
3531 }
Selim Cineke70d6532015-04-24 16:46:13 -07003532 }
3533 };
Jorim Jaggid9449862015-05-29 14:49:08 -07003534 Runnable cancelRunnable = new Runnable() {
3535 @Override
3536 public void run() {
Jorim Jaggi5cc86592015-06-08 14:48:28 -07003537 if (callback != null) {
3538 callback.onActivityStarted(ActivityManager.START_CANCELED);
3539 }
Jorim Jaggid9449862015-05-29 14:49:08 -07003540 }
3541 };
Jorim Jaggib835dd72015-06-08 12:28:42 -07003542 executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShade,
Felipe Lemeee5d6302016-04-22 16:11:19 -07003543 afterKeyguardGone, true /* deferred */);
Selim Cineke70d6532015-04-24 16:46:13 -07003544 }
3545
3546 public void executeRunnableDismissingKeyguard(final Runnable runnable,
Jorim Jaggid9449862015-05-29 14:49:08 -07003547 final Runnable cancelAction,
Selim Cineke70d6532015-04-24 16:46:13 -07003548 final boolean dismissShade,
Felipe Lemeee5d6302016-04-22 16:11:19 -07003549 final boolean afterKeyguardGone,
3550 final boolean deferred) {
Selim Cineke70d6532015-04-24 16:46:13 -07003551 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Adrian Roos4314f6d2014-05-28 14:10:27 +02003552 dismissKeyguardThenExecute(new OnDismissAction() {
3553 @Override
3554 public boolean onDismiss() {
Selim Cinekbaa23272014-07-08 18:01:07 +02003555 AsyncTask.execute(new Runnable() {
Jim Miller07e03842016-06-22 15:18:13 -07003556 @Override
Selim Cinekbaa23272014-07-08 18:01:07 +02003557 public void run() {
3558 try {
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02003559 if (keyguardShowing && !afterKeyguardGone) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003560 ActivityManagerNative.getDefault()
3561 .keyguardWaitingForActivityDrawn();
3562 }
Selim Cineke70d6532015-04-24 16:46:13 -07003563 if (runnable != null) {
3564 runnable.run();
3565 }
Selim Cinekbaa23272014-07-08 18:01:07 +02003566 } catch (RemoteException e) {
3567 }
3568 }
3569 });
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003570 if (dismissShade) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -07003571 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
3572 true /* delayed*/);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003573 }
Felipe Lemeee5d6302016-04-22 16:11:19 -07003574 return deferred;
Adrian Roos4314f6d2014-05-28 14:10:27 +02003575 }
Jorim Jaggid9449862015-05-29 14:49:08 -07003576 }, cancelAction, afterKeyguardGone);
Daniel Sandler3679bf52012-10-16 21:30:28 -04003577 }
3578
Joe Onorato808182d2010-07-09 18:52:06 -04003579 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
Jim Miller07e03842016-06-22 15:18:13 -07003580 @Override
Joe Onorato808182d2010-07-09 18:52:06 -04003581 public void onReceive(Context context, Intent intent) {
John Spurlockcd686b52013-06-05 10:13:46 -04003582 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04003583 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04003584 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Andrei Stingaceanuf86bc972016-04-12 15:29:25 +01003585 KeyboardShortcuts.dismiss();
Adrian Roos07215352016-06-23 11:19:28 -07003586 if (mRemoteInputController != null) {
3587 mRemoteInputController.closeRemoteInputs();
3588 }
Kenny Guy44fc65f2014-11-28 22:18:14 +00003589 if (isCurrentProfile(getSendingUserId())) {
3590 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
3591 String reason = intent.getStringExtra("reason");
3592 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
3593 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
3594 }
3595 animateCollapsePanels(flags);
Michael Jurka3b1fc472011-06-13 10:54:40 -07003596 }
Joe Onorato808182d2010-07-09 18:52:06 -04003597 }
Daniel Sandlered930e52012-07-03 14:31:22 -04003598 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
John Spurlock1bbd49d2012-10-19 11:09:32 -04003599 notifyNavigationBarScreenOn(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07003600 notifyHeadsUpScreenOff();
John Spurlock42197262013-10-21 09:32:25 -04003601 finishBarAnimations();
Selim Cinekccd14fb2014-08-12 18:53:24 +02003602 resetUserExpandedStates();
Daniel Sandlered930e52012-07-03 14:31:22 -04003603 }
Daniel Sandler7f3cf952012-08-31 14:57:09 -04003604 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
John Spurlock1bbd49d2012-10-19 11:09:32 -04003605 notifyNavigationBarScreenOn(true);
Joe Onorato808182d2010-07-09 18:52:06 -04003606 }
phweiss923d2cc2016-12-14 21:37:48 +01003607 else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
3608 mQSPanel.showDeviceMonitoringDialog();
3609 }
Adrian Roos8e3e8362015-07-16 19:42:22 -07003610 }
3611 };
3612
3613 private BroadcastReceiver mDemoReceiver = new BroadcastReceiver() {
Jim Miller07e03842016-06-22 15:18:13 -07003614 @Override
Adrian Roos8e3e8362015-07-16 19:42:22 -07003615 public void onReceive(Context context, Intent intent) {
3616 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
3617 String action = intent.getAction();
3618 if (ACTION_DEMO.equals(action)) {
John Spurlock3c875662013-08-31 15:07:25 -04003619 Bundle bundle = intent.getExtras();
3620 if (bundle != null) {
3621 String command = bundle.getString("command", "").trim().toLowerCase();
3622 if (command.length() > 0) {
3623 try {
3624 dispatchDemoCommand(command, bundle);
3625 } catch (Throwable t) {
3626 Log.w(TAG, "Error running demo command, intent=" + intent, t);
3627 }
3628 }
3629 }
Adrian Roos8e3e8362015-07-16 19:42:22 -07003630 } else if (ACTION_FAKE_ARTWORK.equals(action)) {
Dan Sandler16128f42014-05-21 12:48:22 -04003631 if (DEBUG_MEDIA_FAKE_ARTWORK) {
Adrian Roos52738322016-01-29 08:49:21 -08003632 updateMediaMetaData(true, true);
Dan Sandler16128f42014-05-21 12:48:22 -04003633 }
John Spurlock3c875662013-08-31 15:07:25 -04003634 }
Joe Onorato808182d2010-07-09 18:52:06 -04003635 }
3636 };
3637
Selim Cinek78f40082016-03-10 18:06:27 -08003638 public void resetUserExpandedStates() {
Selim Cinekccd14fb2014-08-12 18:53:24 +02003639 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
3640 final int notificationCount = activeNotifications.size();
3641 for (int i = 0; i < notificationCount; i++) {
3642 NotificationData.Entry entry = activeNotifications.get(i);
3643 if (entry.row != null) {
3644 entry.row.resetUserExpansion();
3645 }
3646 }
3647 }
3648
Adrian Roos7d7090d2014-05-21 13:10:23 +02003649 @Override
Jorim Jaggid9449862015-05-29 14:49:08 -07003650 protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
3651 dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
3652 }
3653
Jason Monkabe19742015-09-29 09:47:06 -04003654 public void dismissKeyguard() {
3655 mStatusBarKeyguardViewManager.dismiss();
3656 }
3657
Jorim Jaggid9449862015-05-29 14:49:08 -07003658 private void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02003659 boolean afterKeyguardGone) {
Adrian Roos7d7090d2014-05-21 13:10:23 +02003660 if (mStatusBarKeyguardViewManager.isShowing()) {
Jorim Jaggid9449862015-05-29 14:49:08 -07003661 mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
3662 afterKeyguardGone);
Adrian Roos7d7090d2014-05-21 13:10:23 +02003663 } else {
3664 action.onDismiss();
3665 }
3666 }
3667
Daniel Sandler777dcde2013-09-30 10:21:45 -04003668 // SystemUIService notifies SystemBars of configuration changes, which then calls down here
3669 @Override
3670 protected void onConfigurationChanged(Configuration newConfig) {
Selim Cinek3e7592d2016-04-11 09:35:54 +08003671 updateResources();
3672 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler777dcde2013-09-30 10:21:45 -04003673 super.onConfigurationChanged(newConfig); // calls refreshLayout
3674
3675 if (DEBUG) {
3676 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
3677 }
Daniel Sandler777dcde2013-09-30 10:21:45 -04003678
Daniel Sandler777dcde2013-09-30 10:21:45 -04003679 repositionNavigationBar();
Jorim Jaggif6411742014-08-05 17:10:43 +00003680 updateRowStates();
Jason Monk18f99d92014-09-11 13:36:42 -04003681 mScreenPinningRequest.onConfigurationChanged();
Jason Monk1c040db2015-07-20 09:45:54 -04003682 mNetworkController.onConfigurationChanged();
Daniel Sandler777dcde2013-09-30 10:21:45 -04003683 }
3684
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003685 @Override
3686 public void userSwitched(int newUserId) {
Chris Wrena6d4fb62014-11-20 14:46:23 -05003687 super.userSwitched(newUserId);
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003688 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04003689 animateCollapsePanels();
Adrian Roos31b844b2014-11-21 13:55:09 +01003690 updatePublicMode();
Christoph Studer37fe6932014-05-26 13:10:30 +02003691 updateNotifications();
John Spurlock919adac2012-10-02 16:41:12 -04003692 resetUserSetupObserver();
John Spurlock89f060a2014-07-16 21:03:15 -04003693 setControllerUsers();
Julia Reynolds86ef8e22015-09-09 16:42:38 -04003694 clearCurrentMediaNotification();
Vadim Tryshev12a30e82016-02-12 15:39:28 -08003695 mLockscreenWallpaper.setCurrentUser(newUserId);
Jorim Jaggie31f6b82016-07-01 16:15:09 -07003696 mScrimController.setCurrentUser(newUserId);
Adrian Roos52738322016-01-29 08:49:21 -08003697 updateMediaMetaData(true, false);
John Spurlock89f060a2014-07-16 21:03:15 -04003698 }
3699
3700 private void setControllerUsers() {
3701 if (mZenModeController != null) {
3702 mZenModeController.setUserId(mCurrentUserId);
3703 }
Robin Lee63204ee2015-06-04 01:53:01 +01003704 if (mSecurityController != null) {
3705 mSecurityController.onUserSwitched(mCurrentUserId);
3706 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003707 }
John Spurlock919adac2012-10-02 16:41:12 -04003708
3709 private void resetUserSetupObserver() {
3710 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
3711 mUserSetupObserver.onChange(false);
3712 mContext.getContentResolver().registerContentObserver(
3713 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003714 mUserSetupObserver, mCurrentUserId);
John Spurlock919adac2012-10-02 16:41:12 -04003715 }
3716
Joe Onorato808182d2010-07-09 18:52:06 -04003717 /**
3718 * Reload some of our resources when the configuration changes.
3719 *
3720 * We don't reload everything when the configuration changes -- we probably
3721 * should, but getting that smooth is tough. Someday we'll fix that. In the
3722 * meantime, just update the things that we know change.
3723 */
3724 void updateResources() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04003725 // Update the quick setting tiles
John Spurlock7e6809a2014-08-06 16:03:14 -04003726 if (mQSPanel != null) {
3727 mQSPanel.updateResources();
3728 }
Winson Chungd63c59782012-09-05 17:34:41 -07003729
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003730 loadDimens();
John Spurlock7e6809a2014-08-06 16:03:14 -04003731
3732 if (mNotificationPanel != null) {
3733 mNotificationPanel.updateResources();
3734 }
Adrian Roos5fd872e2014-08-12 17:28:58 +02003735 if (mBrightnessMirrorController != null) {
3736 mBrightnessMirrorController.updateResources();
3737 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003738 }
Jim Miller5e6af442011-12-02 18:24:26 -08003739
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003740 protected void loadDimens() {
3741 final Resources res = mContext.getResources();
3742
Jorim Jaggi11c62e12016-04-05 20:41:21 -07003743 int oldBarHeight = mNaturalBarHeight;
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003744 mNaturalBarHeight = res.getDimensionPixelSize(
3745 com.android.internal.R.dimen.status_bar_height);
Jorim Jaggi11c62e12016-04-05 20:41:21 -07003746 if (mStatusBarWindowManager != null && mNaturalBarHeight != oldBarHeight) {
3747 mStatusBarWindowManager.setBarHeight(mNaturalBarHeight);
3748 }
3749 mMaxAllowedKeyguardNotifications = res.getInteger(
3750 R.integer.keyguard_max_notification_count);
Jorim Jaggid4a57442014-04-10 02:45:55 +02003751
Selim Cinek3e7592d2016-04-11 09:35:54 +08003752 if (DEBUG) Log.v(TAG, "defineSlots");
John Spurlock804df702012-06-01 15:34:27 -04003753 }
3754
Christoph Studer92b389d2014-04-01 18:44:40 +02003755 // Visibility reporting
3756
3757 @Override
Christoph Studere8e28652014-10-29 17:27:53 +01003758 protected void handleVisibleToUserChanged(boolean visibleToUser) {
3759 if (visibleToUser) {
3760 super.handleVisibleToUserChanged(visibleToUser);
3761 startNotificationLogging();
Christoph Studer92b389d2014-04-01 18:44:40 +02003762 } else {
Christoph Studer037e34c2014-04-30 20:06:04 +02003763 stopNotificationLogging();
Christoph Studere8e28652014-10-29 17:27:53 +01003764 super.handleVisibleToUserChanged(visibleToUser);
Christoph Studer92b389d2014-04-01 18:44:40 +02003765 }
Christoph Studer92b389d2014-04-01 18:44:40 +02003766 }
3767
Christoph Studer037e34c2014-04-30 20:06:04 +02003768 private void stopNotificationLogging() {
3769 // Report all notifications as invisible and turn down the
3770 // reporter.
3771 if (!mCurrentlyVisibleNotifications.isEmpty()) {
Chris Wrend1dbc922015-06-19 17:51:16 -04003772 logNotificationVisibilityChanges(Collections.<NotificationVisibility>emptyList(),
3773 mCurrentlyVisibleNotifications);
3774 recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
Christoph Studer037e34c2014-04-30 20:06:04 +02003775 }
3776 mHandler.removeCallbacks(mVisibilityReporter);
3777 mStackScroller.setChildLocationsChangedListener(null);
3778 }
3779
Christoph Studere8e28652014-10-29 17:27:53 +01003780 private void startNotificationLogging() {
3781 mStackScroller.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
3782 // Some transitions like mVisibleToUser=false -> mVisibleToUser=true don't
3783 // cause the scroller to emit child location events. Hence generate
3784 // one ourselves to guarantee that we're reporting visible
3785 // notifications.
3786 // (Note that in cases where the scroller does emit events, this
3787 // additional event doesn't break anything.)
3788 mNotificationLocationsChangedListener.onChildLocationsChanged(mStackScroller);
Christoph Studer037e34c2014-04-30 20:06:04 +02003789 }
3790
Christoph Studer92b389d2014-04-01 18:44:40 +02003791 private void logNotificationVisibilityChanges(
Chris Wrend1dbc922015-06-19 17:51:16 -04003792 Collection<NotificationVisibility> newlyVisible,
3793 Collection<NotificationVisibility> noLongerVisible) {
Christoph Studer92b389d2014-04-01 18:44:40 +02003794 if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
3795 return;
3796 }
Chris Wrend1dbc922015-06-19 17:51:16 -04003797 NotificationVisibility[] newlyVisibleAr =
3798 newlyVisible.toArray(new NotificationVisibility[newlyVisible.size()]);
3799 NotificationVisibility[] noLongerVisibleAr =
3800 noLongerVisible.toArray(new NotificationVisibility[noLongerVisible.size()]);
Christoph Studer92b389d2014-04-01 18:44:40 +02003801 try {
3802 mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr);
3803 } catch (RemoteException e) {
3804 // Ignore.
3805 }
Chris Wrend1dbc922015-06-19 17:51:16 -04003806
3807 final int N = newlyVisible.size();
Amith Yamasani76495672015-07-07 15:22:54 -07003808 if (N > 0) {
3809 String[] newlyVisibleKeyAr = new String[N];
3810 for (int i = 0; i < N; i++) {
3811 newlyVisibleKeyAr[i] = newlyVisibleAr[i].key;
3812 }
3813
3814 setNotificationsShown(newlyVisibleKeyAr);
Chris Wrend1dbc922015-06-19 17:51:16 -04003815 }
Christoph Studer92b389d2014-04-01 18:44:40 +02003816 }
3817
Christoph Studer2231c6e2014-12-19 12:40:13 +01003818 // State logging
3819
3820 private void logStateToEventlog() {
3821 boolean isShowing = mStatusBarKeyguardViewManager.isShowing();
3822 boolean isOccluded = mStatusBarKeyguardViewManager.isOccluded();
3823 boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing();
3824 boolean isSecure = mUnlockMethodCache.isMethodSecure();
Selim Cineke8bae622015-07-15 13:24:06 -07003825 boolean canSkipBouncer = mUnlockMethodCache.canSkipBouncer();
Christoph Studer2231c6e2014-12-19 12:40:13 +01003826 int stateFingerprint = getLoggingFingerprint(mState,
3827 isShowing,
3828 isOccluded,
3829 isBouncerShowing,
3830 isSecure,
Selim Cineke8bae622015-07-15 13:24:06 -07003831 canSkipBouncer);
Christoph Studer2231c6e2014-12-19 12:40:13 +01003832 if (stateFingerprint != mLastLoggedStateFingerprint) {
3833 EventLogTags.writeSysuiStatusBarState(mState,
3834 isShowing ? 1 : 0,
3835 isOccluded ? 1 : 0,
3836 isBouncerShowing ? 1 : 0,
3837 isSecure ? 1 : 0,
Selim Cineke8bae622015-07-15 13:24:06 -07003838 canSkipBouncer ? 1 : 0);
Christoph Studer2231c6e2014-12-19 12:40:13 +01003839 mLastLoggedStateFingerprint = stateFingerprint;
3840 }
3841 }
3842
3843 /**
3844 * Returns a fingerprint of fields logged to eventlog
3845 */
3846 private static int getLoggingFingerprint(int statusBarState, boolean keyguardShowing,
3847 boolean keyguardOccluded, boolean bouncerShowing, boolean secure,
3848 boolean currentlyInsecure) {
3849 // Reserve 8 bits for statusBarState. We'll never go higher than
3850 // that, right? Riiiight.
3851 return (statusBarState & 0xFF)
3852 | ((keyguardShowing ? 1 : 0) << 8)
3853 | ((keyguardOccluded ? 1 : 0) << 9)
3854 | ((bouncerShowing ? 1 : 0) << 10)
3855 | ((secure ? 1 : 0) << 11)
3856 | ((currentlyInsecure ? 1 : 0) << 12);
3857 }
3858
Joe Onorato808182d2010-07-09 18:52:06 -04003859 //
3860 // tracing
3861 //
3862
3863 void postStartTracing() {
3864 mHandler.postDelayed(mStartTracing, 3000);
3865 }
3866
3867 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04003868 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
3869 Context.VIBRATOR_SERVICE);
John Spurlock7b414672014-07-18 13:02:39 -04003870 vib.vibrate(250, VIBRATION_ATTRIBUTES);
Joe Onorato808182d2010-07-09 18:52:06 -04003871 }
3872
3873 Runnable mStartTracing = new Runnable() {
Jim Miller07e03842016-06-22 15:18:13 -07003874 @Override
Joe Onorato808182d2010-07-09 18:52:06 -04003875 public void run() {
3876 vibrate();
3877 SystemClock.sleep(250);
John Spurlockcd686b52013-06-05 10:13:46 -04003878 Log.d(TAG, "startTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04003879 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
3880 mHandler.postDelayed(mStopTracing, 10000);
3881 }
3882 };
3883
3884 Runnable mStopTracing = new Runnable() {
Jim Miller07e03842016-06-22 15:18:13 -07003885 @Override
Joe Onorato808182d2010-07-09 18:52:06 -04003886 public void run() {
3887 android.os.Debug.stopMethodTracing();
John Spurlockcd686b52013-06-05 10:13:46 -04003888 Log.d(TAG, "stopTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04003889 vibrate();
3890 }
3891 };
Chris Wren0c8275b2012-05-08 13:36:48 -04003892
3893 @Override
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07003894 public boolean shouldDisableNavbarGestures() {
Jorim Jaggi18976a52015-07-24 13:18:19 -07003895 return !isDeviceProvisioned() || (mDisabled1 & StatusBarManager.DISABLE_SEARCH) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07003896 }
Joe Onorato808182d2010-07-09 18:52:06 -04003897
Jason Monkba2318e2015-12-08 09:04:23 -05003898 public void postQSRunnableDismissingKeyguard(final Runnable runnable) {
3899 mHandler.post(new Runnable() {
3900 @Override
3901 public void run() {
3902 mLeaveOpenOnKeyguardHide = true;
Felipe Lemeee5d6302016-04-22 16:11:19 -07003903 executeRunnableDismissingKeyguard(runnable, null, false, false, false);
Jason Monkba2318e2015-12-08 09:04:23 -05003904 }
3905 });
3906 }
3907
Adrian Roos62692b22015-09-11 17:46:23 -07003908 public void postStartActivityDismissingKeyguard(final PendingIntent intent) {
3909 mHandler.post(new Runnable() {
3910 @Override
3911 public void run() {
3912 startPendingIntentDismissingKeyguard(intent);
3913 }
3914 });
3915 }
3916
Jason Monkee43cdf2015-06-19 14:20:46 -04003917 public void postStartActivityDismissingKeyguard(final Intent intent, int delay) {
John Spurlockd47a3f32014-05-18 19:14:14 -04003918 mHandler.postDelayed(new Runnable() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04003919 @Override
3920 public void run() {
Jason Monkee43cdf2015-06-19 14:20:46 -04003921 handleStartActivityDismissingKeyguard(intent, true /*onlyProvisioned*/);
John Spurlockaf8d6c42014-05-07 17:49:08 -04003922 }
John Spurlockd47a3f32014-05-18 19:14:14 -04003923 }, delay);
John Spurlockaf8d6c42014-05-07 17:49:08 -04003924 }
3925
Jason Monkee43cdf2015-06-19 14:20:46 -04003926 private void handleStartActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) {
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02003927 startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
John Spurlockde547002014-02-28 17:50:39 -05003928 }
3929
Romain Guy648342f2012-05-25 10:44:45 -07003930 private static class FastColorDrawable extends Drawable {
3931 private final int mColor;
3932
3933 public FastColorDrawable(int color) {
3934 mColor = 0xff000000 | color;
3935 }
3936
3937 @Override
3938 public void draw(Canvas canvas) {
3939 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
3940 }
3941
3942 @Override
3943 public void setAlpha(int alpha) {
3944 }
3945
3946 @Override
Chris Craikbd3bfc52015-03-02 10:43:29 -08003947 public void setColorFilter(ColorFilter colorFilter) {
Romain Guy648342f2012-05-25 10:44:45 -07003948 }
3949
3950 @Override
3951 public int getOpacity() {
3952 return PixelFormat.OPAQUE;
3953 }
3954
3955 @Override
3956 public void setBounds(int left, int top, int right, int bottom) {
3957 }
3958
3959 @Override
3960 public void setBounds(Rect bounds) {
3961 }
3962 }
John Spurlock5c454122013-06-17 07:35:46 -04003963
3964 @Override
3965 public void destroy() {
3966 super.destroy();
3967 if (mStatusBarWindow != null) {
3968 mWindowManager.removeViewImmediate(mStatusBarWindow);
John Spurlockab847cf2014-01-15 14:13:59 -05003969 mStatusBarWindow = null;
John Spurlock5c454122013-06-17 07:35:46 -04003970 }
3971 if (mNavigationBarView != null) {
3972 mWindowManager.removeViewImmediate(mNavigationBarView);
John Spurlockab847cf2014-01-15 14:13:59 -05003973 mNavigationBarView = null;
John Spurlock5c454122013-06-17 07:35:46 -04003974 }
Jason Monk4ae97d32014-12-17 10:14:33 -05003975 if (mHandlerThread != null) {
3976 mHandlerThread.quitSafely();
3977 mHandlerThread = null;
3978 }
John Spurlock5c454122013-06-17 07:35:46 -04003979 mContext.unregisterReceiver(mBroadcastReceiver);
Adrian Roos8e3e8362015-07-16 19:42:22 -07003980 mContext.unregisterReceiver(mDemoReceiver);
Selim Cineke70d6532015-04-24 16:46:13 -07003981 mAssistManager.destroy();
Jason Monk07b75fe2015-05-14 16:47:03 -04003982
3983 final SignalClusterView signalCluster =
3984 (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
3985 final SignalClusterView signalClusterKeyguard =
3986 (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
3987 final SignalClusterView signalClusterQs =
3988 (SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
Jason Monk5e745172015-06-02 19:14:44 -04003989 mNetworkController.removeSignalCallback(signalCluster);
3990 mNetworkController.removeSignalCallback(signalClusterKeyguard);
3991 mNetworkController.removeSignalCallback(signalClusterQs);
3992 if (mQSPanel != null && mQSPanel.getHost() != null) {
3993 mQSPanel.getHost().destroy();
3994 }
John Spurlock5c454122013-06-17 07:35:46 -04003995 }
John Spurlock3c875662013-08-31 15:07:25 -04003996
3997 private boolean mDemoModeAllowed;
3998 private boolean mDemoMode;
John Spurlock3c875662013-08-31 15:07:25 -04003999
4000 @Override
4001 public void dispatchDemoCommand(String command, Bundle args) {
4002 if (!mDemoModeAllowed) {
4003 mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
Jason Monk431ad732015-07-16 08:58:15 -04004004 DEMO_MODE_ALLOWED, 0) != 0;
John Spurlock3c875662013-08-31 15:07:25 -04004005 }
4006 if (!mDemoModeAllowed) return;
4007 if (command.equals(COMMAND_ENTER)) {
4008 mDemoMode = true;
4009 } else if (command.equals(COMMAND_EXIT)) {
4010 mDemoMode = false;
4011 checkBarModes();
4012 } else if (!mDemoMode) {
4013 // automatically enter demo mode on first demo command
4014 dispatchDemoCommand(COMMAND_ENTER, new Bundle());
4015 }
4016 boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
John Spurlockbb4a7022014-11-08 12:40:19 -05004017 if ((modeChange || command.equals(COMMAND_VOLUME)) && mVolumeComponent != null) {
4018 mVolumeComponent.dispatchDemoCommand(command, args);
4019 }
John Spurlock3c875662013-08-31 15:07:25 -04004020 if (modeChange || command.equals(COMMAND_CLOCK)) {
4021 dispatchDemoCommandToView(command, args, R.id.clock);
4022 }
4023 if (modeChange || command.equals(COMMAND_BATTERY)) {
Jason Monk98d7c7a2016-04-12 13:08:31 -04004024 mBatteryController.dispatchDemoCommand(command, args);
John Spurlock3c875662013-08-31 15:07:25 -04004025 }
4026 if (modeChange || command.equals(COMMAND_STATUS)) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01004027 mIconController.dispatchDemoCommand(command, args);
John Spurlock3c875662013-08-31 15:07:25 -04004028 }
4029 if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
4030 mNetworkController.dispatchDemoCommand(command, args);
4031 }
John Spurlock7f42fc52014-01-14 16:20:39 -05004032 if (modeChange || command.equals(COMMAND_NOTIFICATIONS)) {
4033 View notifications = mStatusBarView == null ? null
4034 : mStatusBarView.findViewById(R.id.notification_icon_area);
4035 if (notifications != null) {
4036 String visible = args.getString("visible");
4037 int vis = mDemoMode && "false".equals(visible) ? View.INVISIBLE : View.VISIBLE;
4038 notifications.setVisibility(vis);
4039 }
4040 }
John Spurlock3c875662013-08-31 15:07:25 -04004041 if (command.equals(COMMAND_BARS)) {
4042 String mode = args.getString("mode");
4043 int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
John Spurlockbd957402013-10-03 11:38:39 -04004044 "translucent".equals(mode) ? MODE_TRANSLUCENT :
John Spurlock3c875662013-08-31 15:07:25 -04004045 "semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
John Spurlock0ff62e02014-07-22 16:15:08 -04004046 "transparent".equals(mode) ? MODE_TRANSPARENT :
4047 "warning".equals(mode) ? MODE_WARNING :
John Spurlock3c875662013-08-31 15:07:25 -04004048 -1;
4049 if (barMode != -1) {
4050 boolean animate = true;
4051 if (mStatusBarView != null) {
4052 mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
4053 }
4054 if (mNavigationBarView != null) {
4055 mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
4056 }
4057 }
4058 }
4059 }
4060
4061 private void dispatchDemoCommandToView(String command, Bundle args, int id) {
4062 if (mStatusBarView == null) return;
4063 View v = mStatusBarView.findViewById(id);
4064 if (v instanceof DemoMode) {
4065 ((DemoMode)v).dispatchDemoCommand(command, args);
4066 }
4067 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004068
Jorim Jaggiecbab362014-04-23 16:13:15 +02004069 /**
4070 * @return The {@link StatusBarState} the status bar is in.
4071 */
4072 public int getBarState() {
4073 return mState;
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004074 }
4075
Chris Wren16895942015-06-23 11:22:20 -04004076 @Override
Yorke Leee4ea6ab2016-03-03 14:51:49 -08004077 public boolean isPanelFullyCollapsed() {
Chris Wren16895942015-06-23 11:22:20 -04004078 return mNotificationPanel.isFullyCollapsed();
4079 }
4080
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004081 public void showKeyguard() {
Jorim Jaggi5e08e692014-10-03 15:17:20 -07004082 if (mLaunchTransitionFadingAway) {
4083 mNotificationPanel.animate().cancel();
Selim Cinek37c110f2015-05-22 12:38:44 -07004084 onLaunchTransitionFadingEnded();
Jorim Jaggi5e08e692014-10-03 15:17:20 -07004085 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01004086 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004087 if (mUserSwitcherController != null && mUserSwitcherController.useFullscreenUserSwitcher()) {
4088 setBarState(StatusBarState.FULLSCREEN_USER_SWITCHER);
4089 } else {
4090 setBarState(StatusBarState.KEYGUARD);
4091 }
Jorim Jaggi98f85302014-08-07 17:45:04 +02004092 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004093 if (!mDeviceInteractive) {
Jorim Jaggid41083a2014-09-12 02:54:40 +02004094
4095 // If the screen is off already, we need to disable touch events because these might
4096 // collapse the panel after we expanded it, and thus we would end up with a blank
4097 // Keyguard.
4098 mNotificationPanel.setTouchDisabled(true);
4099 }
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004100 if (mState == StatusBarState.KEYGUARD) {
4101 instantExpandNotificationsPanel();
4102 } else if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
4103 instantCollapseNotificationPanel();
4104 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02004105 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004106 if (mDraggedDownRow != null) {
4107 mDraggedDownRow.setUserLocked(false);
Selim Cinekb5605e52015-02-20 18:21:41 +01004108 mDraggedDownRow.notifyHeightChanged(false /* needsAnimation */);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004109 mDraggedDownRow = null;
4110 }
Adrian Roos3aec6382016-02-05 14:19:01 -08004111 mPendingRemoteInputView = null;
Jorim Jaggi19695d92015-07-20 15:51:40 -07004112 mAssistManager.onLockscreenShown();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004113 }
4114
Selim Cinek37c110f2015-05-22 12:38:44 -07004115 private void onLaunchTransitionFadingEnded() {
4116 mNotificationPanel.setAlpha(1.0f);
Selim Cinek372d1bd2015-08-14 13:19:37 -07004117 mNotificationPanel.onAffordanceLaunchEnded();
4118 releaseGestureWakeLock();
Selim Cinek37c110f2015-05-22 12:38:44 -07004119 runLaunchTransitionEndRunnable();
4120 mLaunchTransitionFadingAway = false;
4121 mScrimController.forceHideScrims(false /* hide */);
Adrian Roos52738322016-01-29 08:49:21 -08004122 updateMediaMetaData(true /* metaDataChanged */, true);
Selim Cinek37c110f2015-05-22 12:38:44 -07004123 }
4124
Selim Cinek36b02232016-05-11 23:07:05 -04004125 @Override
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02004126 public boolean isCollapsing() {
4127 return mNotificationPanel.isCollapsing();
4128 }
4129
Selim Cinek36b02232016-05-11 23:07:05 -04004130 @Override
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02004131 public void addPostCollapseAction(Runnable r) {
4132 mPostCollapseRunnables.add(r);
4133 }
4134
Selim Cinekbaa23272014-07-08 18:01:07 +02004135 public boolean isInLaunchTransition() {
4136 return mNotificationPanel.isLaunchTransitionRunning()
4137 || mNotificationPanel.isLaunchTransitionFinished();
4138 }
4139
4140 /**
4141 * Fades the content of the keyguard away after the launch transition is done.
4142 *
4143 * @param beforeFading the runnable to be run when the circle is fully expanded and the fading
4144 * starts
4145 * @param endRunnable the runnable to be run when the transition is done
4146 */
4147 public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
Jorim Jaggi5e08e692014-10-03 15:17:20 -07004148 Runnable endRunnable) {
Jorim Jaggi826730a2014-12-08 21:05:13 +01004149 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggi5e08e692014-10-03 15:17:20 -07004150 mLaunchTransitionEndRunnable = endRunnable;
Selim Cinekbaa23272014-07-08 18:01:07 +02004151 Runnable hideRunnable = new Runnable() {
4152 @Override
4153 public void run() {
4154 mLaunchTransitionFadingAway = true;
4155 if (beforeFading != null) {
4156 beforeFading.run();
4157 }
Selim Cinek37c110f2015-05-22 12:38:44 -07004158 mScrimController.forceHideScrims(true /* hide */);
Adrian Roos52738322016-01-29 08:49:21 -08004159 updateMediaMetaData(false, true);
Selim Cinekbaa23272014-07-08 18:01:07 +02004160 mNotificationPanel.setAlpha(1);
Selim Cinek07304f5222016-05-19 18:31:36 -07004161 mStackScroller.setParentFadingOut(true);
Selim Cinekbaa23272014-07-08 18:01:07 +02004162 mNotificationPanel.animate()
4163 .alpha(0)
4164 .setStartDelay(FADE_KEYGUARD_START_DELAY)
4165 .setDuration(FADE_KEYGUARD_DURATION)
4166 .withLayer()
4167 .withEndAction(new Runnable() {
4168 @Override
4169 public void run() {
Selim Cinek37c110f2015-05-22 12:38:44 -07004170 onLaunchTransitionFadingEnded();
Selim Cinekbaa23272014-07-08 18:01:07 +02004171 }
4172 });
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004173 mIconController.appTransitionStarting(SystemClock.uptimeMillis(),
4174 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Selim Cinekbaa23272014-07-08 18:01:07 +02004175 }
4176 };
4177 if (mNotificationPanel.isLaunchTransitionRunning()) {
4178 mNotificationPanel.setLaunchTransitionEndRunnable(hideRunnable);
4179 } else {
4180 hideRunnable.run();
4181 }
4182 }
4183
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004184 /**
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004185 * Fades the content of the Keyguard while we are dozing and makes it invisible when finished
4186 * fading.
4187 */
4188 public void fadeKeyguardWhilePulsing() {
4189 mNotificationPanel.animate()
4190 .alpha(0f)
4191 .setStartDelay(0)
4192 .setDuration(FADE_KEYGUARD_DURATION_PULSING)
Jorim Jaggiab45a212015-08-20 16:59:44 -07004193 .setInterpolator(ScrimController.KEYGUARD_FADE_OUT_INTERPOLATOR)
4194 .start();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004195 }
4196
4197 /**
Jorim Jaggi6626f542016-08-22 13:08:44 -07004198 * Plays the animation when an activity that was occluding Keyguard goes away.
4199 */
4200 public void animateKeyguardUnoccluding() {
4201 mScrimController.animateKeyguardUnoccluding(500);
4202 mNotificationPanel.setExpandedFraction(0f);
4203 animateExpandNotificationsPanel();
4204 }
4205
4206 /**
Jorim Jaggi826730a2014-12-08 21:05:13 +01004207 * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
4208 * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
4209 * because the launched app crashed or something else went wrong.
4210 */
4211 public void startLaunchTransitionTimeout() {
4212 mHandler.sendEmptyMessageDelayed(MSG_LAUNCH_TRANSITION_TIMEOUT,
4213 LAUNCH_TRANSITION_TIMEOUT_MS);
4214 }
4215
4216 private void onLaunchTransitionTimeout() {
4217 Log.w(TAG, "Launch transition: Timeout!");
Selim Cinek372d1bd2015-08-14 13:19:37 -07004218 mNotificationPanel.onAffordanceLaunchEnded();
4219 releaseGestureWakeLock();
Jorim Jaggi826730a2014-12-08 21:05:13 +01004220 mNotificationPanel.resetViews();
4221 }
4222
4223 private void runLaunchTransitionEndRunnable() {
4224 if (mLaunchTransitionEndRunnable != null) {
4225 Runnable r = mLaunchTransitionEndRunnable;
4226
4227 // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
4228 // which would lead to infinite recursion. Protect against it.
4229 mLaunchTransitionEndRunnable = null;
4230 r.run();
4231 }
4232 }
4233
4234 /**
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004235 * @return true if we would like to stay in the shade, false if it should go away entirely
4236 */
4237 public boolean hideKeyguard() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07004238 Trace.beginSection("PhoneStatusBar#hideKeyguard");
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004239 boolean staying = mLeaveOpenOnKeyguardHide;
Jorim Jaggiecbab362014-04-23 16:13:15 +02004240 setBarState(StatusBarState.SHADE);
Adrian Roos3aec6382016-02-05 14:19:01 -08004241 View viewToClick = null;
Jorim Jaggiecbab362014-04-23 16:13:15 +02004242 if (mLeaveOpenOnKeyguardHide) {
4243 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggi37c11802015-08-18 20:27:54 -07004244 long delay = calculateGoingToFullShadeDelay();
4245 mNotificationPanel.animateToFullShade(delay);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004246 if (mDraggedDownRow != null) {
4247 mDraggedDownRow.setUserLocked(false);
4248 mDraggedDownRow = null;
4249 }
Adrian Roos3aec6382016-02-05 14:19:01 -08004250 viewToClick = mPendingRemoteInputView;
4251 mPendingRemoteInputView = null;
Jorim Jaggi37c11802015-08-18 20:27:54 -07004252
4253 // Disable layout transitions in navbar for this transition because the load is just
4254 // too heavy for the CPU and GPU on any device.
4255 if (mNavigationBarView != null) {
4256 mNavigationBarView.setLayoutTransitionsEnabled(false);
4257 mNavigationBarView.postDelayed(new Runnable() {
4258 @Override
4259 public void run() {
4260 mNavigationBarView.setLayoutTransitionsEnabled(true);
4261 }
4262 }, delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
4263 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02004264 } else {
4265 instantCollapseNotificationPanel();
4266 }
Jorim Jaggi98f85302014-08-07 17:45:04 +02004267 updateKeyguardState(staying, false /* fromShadeLocked */);
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +01004268
Adrian Roosb22665d2016-10-17 15:08:03 -07004269 if (viewToClick != null && viewToClick.isAttachedToWindow()) {
Adrian Roos3aec6382016-02-05 14:19:01 -08004270 viewToClick.callOnClick();
4271 }
4272
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +01004273 // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
4274 // visibilities so next time we open the panel we know the correct height already.
4275 if (mQSPanel != null) {
4276 mQSPanel.refreshAllTiles();
4277 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01004278 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Selim Cinek372d1bd2015-08-14 13:19:37 -07004279 releaseGestureWakeLock();
4280 mNotificationPanel.onAffordanceLaunchEnded();
Jorim Jaggi52429b42015-09-03 19:58:19 -07004281 mNotificationPanel.animate().cancel();
Jorim Jaggi90978852015-08-18 19:55:53 -07004282 mNotificationPanel.setAlpha(1f);
Nick Desaulniers1d396752016-07-25 15:05:33 -07004283 Trace.endSection();
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004284 return staying;
4285 }
4286
Selim Cinek372d1bd2015-08-14 13:19:37 -07004287 private void releaseGestureWakeLock() {
4288 if (mGestureWakeLock.isHeld()) {
4289 mGestureWakeLock.release();
4290 }
4291 }
4292
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004293 public long calculateGoingToFullShadeDelay() {
4294 return mKeyguardFadingAwayDelay + mKeyguardFadingAwayDuration;
Jorim Jaggi15682502014-04-23 12:01:36 +02004295 }
4296
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004297 /**
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004298 * Notifies the status bar that Keyguard is going away very soon.
4299 */
4300 public void keyguardGoingAway() {
4301
4302 // Treat Keyguard exit animation as an app transition to achieve nice transition for status
4303 // bar.
Adrian Roos46df1ca2015-09-11 12:38:43 -07004304 mKeyguardGoingAway = true;
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004305 mIconController.appTransitionPending();
4306 }
4307
4308 /**
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004309 * Notifies the status bar the Keyguard is fading away with the specified timings.
4310 *
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004311 * @param startTime the start time of the animations in uptime millis
4312 * @param delay the precalculated animation delay in miliseconds
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004313 * @param fadeoutDuration the duration of the exit animation, in milliseconds
4314 */
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004315 public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration) {
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004316 mKeyguardFadingAway = true;
4317 mKeyguardFadingAwayDelay = delay;
4318 mKeyguardFadingAwayDuration = fadeoutDuration;
4319 mWaitingForKeyguardExit = false;
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004320 mIconController.appTransitionStarting(
4321 startTime + fadeoutDuration
4322 - StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION,
4323 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Adrian Roos316bf542016-08-23 17:53:07 +02004324 recomputeDisableFlags(fadeoutDuration > 0 /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004325 }
4326
Jorim Jaggi416493b2014-09-13 03:57:32 +02004327 public boolean isKeyguardFadingAway() {
4328 return mKeyguardFadingAway;
4329 }
4330
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004331 /**
4332 * Notifies that the Keyguard fading away animation is done.
4333 */
4334 public void finishKeyguardFadingAway() {
4335 mKeyguardFadingAway = false;
Adrian Roos46df1ca2015-09-11 12:38:43 -07004336 mKeyguardGoingAway = false;
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004337 }
4338
Adrian Roosd322f1a2015-04-23 15:19:45 -07004339 public void stopWaitingForKeyguardExit() {
4340 mWaitingForKeyguardExit = false;
4341 }
4342
Jorim Jaggi15682502014-04-23 12:01:36 +02004343 private void updatePublicMode() {
Tony Mak92c989d2016-04-19 14:02:44 +01004344 boolean isPublic = false;
4345 if (mStatusBarKeyguardViewManager.isShowing()) {
4346 for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) {
4347 UserInfo userInfo = mCurrentProfiles.valueAt(i);
4348 if (mStatusBarKeyguardViewManager.isSecure(userInfo.id)) {
4349 isPublic = true;
4350 break;
4351 }
4352 }
4353 }
4354 setLockscreenPublicMode(isPublic);
Jorim Jaggi15682502014-04-23 12:01:36 +02004355 }
4356
Rakesh Iyer2790a372016-01-22 15:33:39 -08004357 protected void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07004358 Trace.beginSection("PhoneStatusBar#updateKeyguardState");
Jorim Jaggiecbab362014-04-23 16:13:15 +02004359 if (mState == StatusBarState.KEYGUARD) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02004360 mKeyguardIndicationController.setVisible(true);
Selim Cinek4c6969a2014-05-26 19:22:17 +02004361 mNotificationPanel.resetViews();
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004362 if (mKeyguardUserSwitcher != null) {
4363 mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
4364 }
Selim Cinek80c2abe2015-06-17 15:37:30 -07004365 mStatusBarView.removePendingHideExpandedRunnables();
Jorim Jaggi15682502014-04-23 12:01:36 +02004366 } else {
Adrian Roos12c1ef52014-06-04 13:54:08 +02004367 mKeyguardIndicationController.setVisible(false);
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004368 if (mKeyguardUserSwitcher != null) {
4369 mKeyguardUserSwitcher.setKeyguard(false,
4370 goingToFullShade ||
4371 mState == StatusBarState.SHADE_LOCKED ||
4372 fromShadeLocked);
4373 }
Jorim Jaggi15682502014-04-23 12:01:36 +02004374 }
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004375 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02004376 mScrimController.setKeyguardShowing(true);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004377 } else {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02004378 mScrimController.setKeyguardShowing(false);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004379 }
Nicolas Prevot1dbbe7d2016-05-17 12:52:54 +01004380 mIconPolicy.notifyKeyguardShowingChanged();
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004381 mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
John Spurlockbf370992014-06-17 13:58:31 -04004382 updateDozingState();
Jorim Jaggi15682502014-04-23 12:01:36 +02004383 updatePublicMode();
Selim Cinekd35c2792016-01-21 13:20:57 -08004384 updateStackScrollerState(goingToFullShade, fromShadeLocked);
Christoph Studer37fe6932014-05-26 13:10:30 +02004385 updateNotifications();
Jorim Jaggia6310292014-04-16 14:11:52 +02004386 checkBarModes();
Adrian Roos52738322016-01-29 08:49:21 -08004387 updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
John Spurlock657c62c2014-07-22 12:18:09 -04004388 mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
Jim Miller69c12412016-10-06 19:11:03 -07004389 mStatusBarKeyguardViewManager.isSecure(),
4390 mStatusBarKeyguardViewManager.isOccluded());
Nick Desaulniers1d396752016-07-25 15:05:33 -07004391 Trace.endSection();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004392 }
4393
John Spurlockbf370992014-06-17 13:58:31 -04004394 private void updateDozingState() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07004395 Trace.beginSection("PhoneStatusBar#updateDozingState");
Jorim Jaggi4e857f42014-11-17 19:14:04 +01004396 boolean animate = !mDozing && mDozeScrimController.isPulsing();
4397 mNotificationPanel.setDozing(mDozing, animate);
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004398 mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation);
Jorim Jaggi048af1f2014-11-11 22:51:10 +01004399 mScrimController.setDozing(mDozing);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004400
4401 // Immediately abort the dozing from the doze scrim controller in case of wake-and-unlock
4402 // for pulsing so the Keyguard fade-out animation scrim can take over.
4403 mDozeScrimController.setDozing(mDozing &&
4404 mFingerprintUnlockController.getMode()
4405 != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING, animate);
Nick Desaulniers1d396752016-07-25 15:05:33 -07004406 Trace.endSection();
John Spurlockbf370992014-06-17 13:58:31 -04004407 }
4408
Selim Cinekd35c2792016-01-21 13:20:57 -08004409 public void updateStackScrollerState(boolean goingToFullShade, boolean fromShadeLocked) {
John Spurlock4b3bda22014-05-22 14:32:20 -04004410 if (mStackScroller == null) return;
Selim Cinek1408eb52014-06-02 14:45:38 +02004411 boolean onKeyguard = mState == StatusBarState.KEYGUARD;
Jorim Jaggiae441282014-08-01 02:45:18 +02004412 mStackScroller.setHideSensitive(isLockscreenPublicMode(), goingToFullShade);
Selim Cinekd35c2792016-01-21 13:20:57 -08004413 mStackScroller.setDimmed(onKeyguard, fromShadeLocked /* animate */);
Selim Cinek1408eb52014-06-02 14:45:38 +02004414 mStackScroller.setExpandingEnabled(!onKeyguard);
Selim Cineka32ab602014-06-11 15:06:01 +02004415 ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
4416 mStackScroller.setActivatedChild(null);
4417 if (activatedChild != null) {
4418 activatedChild.makeInactive(false /* animate */);
4419 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004420 }
4421
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004422 public void userActivity() {
Jorim Jaggib690f0d2014-07-03 23:25:44 +02004423 if (mState == StatusBarState.KEYGUARD) {
4424 mKeyguardViewMediatorCallback.userActivity();
4425 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004426 }
4427
Jorim Jaggidf993512014-05-13 23:06:35 +02004428 public boolean interceptMediaKey(KeyEvent event) {
4429 return mState == StatusBarState.KEYGUARD
4430 && mStatusBarKeyguardViewManager.interceptMediaKey(event);
4431 }
4432
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02004433 public boolean onMenuPressed() {
Selim Cinek28540192016-02-19 17:25:08 -08004434 if (mDeviceInteractive && mState != StatusBarState.SHADE
4435 && mStatusBarKeyguardViewManager.shouldDismissOnMenuPressed()) {
4436 animateCollapsePanels(
4437 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
4438 return true;
4439 }
4440 return false;
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02004441 }
4442
Selim Cinek372d1bd2015-08-14 13:19:37 -07004443 public void endAffordanceLaunch() {
4444 releaseGestureWakeLock();
4445 mNotificationPanel.onAffordanceLaunchEnded();
4446 }
4447
Jorim Jaggie5c7a892014-04-10 20:37:32 +02004448 public boolean onBackPressed() {
Adrian Roos0002a452014-07-03 13:46:07 +02004449 if (mStatusBarKeyguardViewManager.onBackPressed()) {
Jorim Jaggie5c7a892014-04-10 20:37:32 +02004450 return true;
4451 }
Adrian Roos0002a452014-07-03 13:46:07 +02004452 if (mNotificationPanel.isQsExpanded()) {
John Spurlockf7ae4422014-08-01 12:45:18 -04004453 if (mNotificationPanel.isQsDetailShowing()) {
4454 mNotificationPanel.closeQsDetail();
4455 } else {
4456 mNotificationPanel.animateCloseQs();
4457 }
Adrian Roos0002a452014-07-03 13:46:07 +02004458 return true;
4459 }
4460 if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) {
4461 animateCollapsePanels();
4462 return true;
4463 }
4464 return false;
Jorim Jaggie5c7a892014-04-10 20:37:32 +02004465 }
4466
Jorim Jaggi34250762014-07-03 23:51:19 +02004467 public boolean onSpacePressed() {
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004468 if (mDeviceInteractive && mState != StatusBarState.SHADE) {
Jorim Jaggi4eedc1d2014-10-27 13:45:56 +01004469 animateCollapsePanels(
4470 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
Jorim Jaggi34250762014-07-03 23:51:19 +02004471 return true;
4472 }
4473 return false;
4474 }
4475
Adrian Roosf37fce52016-12-13 15:12:02 -08004476 private void showBouncerIfKeyguard() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02004477 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Adrian Roosf37fce52016-12-13 15:12:02 -08004478 showBouncer();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004479 }
4480 }
4481
Adrian Roosf37fce52016-12-13 15:12:02 -08004482 private void showBouncer() {
4483 mWaitingForKeyguardExit = mStatusBarKeyguardViewManager.isShowing();
4484 mStatusBarKeyguardViewManager.dismiss();
4485 }
4486
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004487 private void instantExpandNotificationsPanel() {
Jorim Jaggic357ca22014-04-25 14:56:15 +02004488
Jorim Jaggi0a27be82014-06-11 03:22:39 +02004489 // Make our window larger and the panel expanded.
Jorim Jaggifa505a72014-04-28 20:04:11 +02004490 makeExpandedVisible(true);
Oren Blasberg8d3fea12015-07-10 14:21:44 -07004491 mNotificationPanel.expand(false /* animate */);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004492 }
Adrian Roos5a46cd32014-04-03 16:51:58 +02004493
Jorim Jaggia005f1b2014-04-16 19:06:10 +02004494 private void instantCollapseNotificationPanel() {
Selim Cinek6bb4a9b2014-10-09 17:48:05 -07004495 mNotificationPanel.instantCollapse();
Jorim Jaggia005f1b2014-04-16 19:06:10 +02004496 }
4497
Jorim Jaggid4a57442014-04-10 02:45:55 +02004498 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02004499 public void onActivated(ActivatableNotificationView view) {
Christoph Studerb0183992014-12-22 21:02:26 +01004500 EventLogTags.writeSysuiLockscreenGesture(
4501 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE,
4502 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
Adrian Roos12c1ef52014-06-04 13:54:08 +02004503 mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
Selim Cineka32ab602014-06-11 15:06:01 +02004504 ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
4505 if (previousView != null) {
4506 previousView.makeInactive(true /* animate */);
4507 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004508 mStackScroller.setActivatedChild(view);
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02004509 }
4510
Annie Chinedeb5172016-06-24 17:07:08 -07004511 public ButtonDispatcher getHomeButton() {
4512 return mNavigationBarView.getHomeButton();
4513 }
4514
Jorim Jaggiecbab362014-04-23 16:13:15 +02004515 /**
4516 * @param state The {@link StatusBarState} to set.
4517 */
4518 public void setBarState(int state) {
Christoph Studer2231c6e2014-12-19 12:40:13 +01004519 // If we're visible and switched to SHADE_LOCKED (the user dragged
4520 // down on the lockscreen), clear notification LED, vibration,
4521 // ringing.
4522 // Other transitions are covered in handleVisibleToUserChanged().
Selim Cinek6577cae2015-08-31 16:15:49 -07004523 if (state != mState && mVisible && (state == StatusBarState.SHADE_LOCKED
4524 || (state == StatusBarState.SHADE && isGoingToNotificationShade()))) {
4525 clearNotificationEffects();
Christoph Studer1f32c652014-11-26 15:32:20 +01004526 }
Adrian Roos18d099a2016-05-19 15:28:18 -07004527 if (state == StatusBarState.KEYGUARD) {
4528 removeRemoteInputEntriesKeptUntilCollapsed();
Selim Cinek99415392016-09-09 14:58:41 -07004529 maybeEscalateHeadsUp();
Adrian Roos18d099a2016-05-19 15:28:18 -07004530 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02004531 mState = state;
Selim Cinek9c4c4142015-12-04 16:44:56 -08004532 mGroupManager.setStatusBarState(state);
Selim Cinekab24dc92016-12-21 18:23:11 +01004533 mHeadsUpManager.setStatusBarState(state);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004534 mFalsingManager.setStatusBarState(state);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004535 mStatusBarWindowManager.setStatusBarState(state);
Adrian Roos7bb38a92016-07-21 11:44:01 -07004536 updateReportRejectedTouchVisibility();
Jorim Jaggi83969702015-06-05 14:59:24 -07004537 updateDozing();
Jorim Jaggiecbab362014-04-23 16:13:15 +02004538 }
4539
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02004540 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02004541 public void onActivationReset(ActivatableNotificationView view) {
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004542 if (view == mStackScroller.getActivatedChild()) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02004543 mKeyguardIndicationController.hideTransientIndication();
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004544 mStackScroller.setActivatedChild(null);
4545 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004546 }
4547
4548 public void onTrackingStarted() {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02004549 runPostCollapseRunnables();
Jorim Jaggi90129582014-06-02 14:44:49 +02004550 }
4551
Selim Cinekdbbcfbe2014-10-24 17:52:35 +02004552 public void onClosingFinished() {
4553 runPostCollapseRunnables();
4554 }
4555
Jorim Jaggi90129582014-06-02 14:44:49 +02004556 public void onUnlockHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004557 mFalsingManager.onUnlockHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004558 mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
Jorim Jaggi90129582014-06-02 14:44:49 +02004559 }
4560
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004561 public void onHintFinished() {
Jorim Jaggi93a2bb22014-06-02 19:57:28 +02004562 // Delay the reset a bit so the user can read the text.
Adrian Roos12c1ef52014-06-04 13:54:08 +02004563 mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004564 }
4565
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004566 public void onCameraHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004567 mFalsingManager.onCameraHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004568 mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004569 }
4570
Selim Cineke70d6532015-04-24 16:46:13 -07004571 public void onVoiceAssistHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004572 mFalsingManager.onLeftAffordanceHintStarted();
Selim Cineke70d6532015-04-24 16:46:13 -07004573 mKeyguardIndicationController.showTransientIndication(R.string.voice_hint);
4574 }
4575
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004576 public void onPhoneHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004577 mFalsingManager.onLeftAffordanceHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004578 mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004579 }
4580
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004581 public void onTrackingStopped(boolean expand) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004582 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Selim Cineke8bae622015-07-15 13:24:06 -07004583 if (!expand && !mUnlockMethodCache.canSkipBouncer()) {
Adrian Roosf37fce52016-12-13 15:12:02 -08004584 showBouncerIfKeyguard();
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004585 }
4586 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004587 }
4588
4589 @Override
Selim Cinek5f71bee2015-11-18 10:25:23 -08004590 protected int getMaxKeyguardNotifications(boolean recompute) {
4591 if (recompute) {
4592 mMaxKeyguardNotifications = Math.max(1,
4593 mNotificationPanel.computeMaxKeyguardNotifications(
4594 mMaxAllowedKeyguardNotifications));
4595 return mMaxKeyguardNotifications;
4596 }
4597 return mMaxKeyguardNotifications;
4598 }
4599
4600 public int getMaxKeyguardNotifications() {
4601 return getMaxKeyguardNotifications(false /* recompute */);
Jorim Jaggid4a57442014-04-10 02:45:55 +02004602 }
4603
Jorim Jaggia6310292014-04-16 14:11:52 +02004604 public NavigationBarView getNavigationBarView() {
4605 return mNavigationBarView;
4606 }
4607
Jorim Jaggiecbab362014-04-23 16:13:15 +02004608 // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
4609
Chris Wren6abeeb92016-05-26 14:44:38 -04004610
4611 /* Only ever called as a consequence of a lockscreen expansion gesture. */
Jorim Jaggiecbab362014-04-23 16:13:15 +02004612 @Override
Christoph Studerb0183992014-12-22 21:02:26 +01004613 public boolean onDraggedDown(View startingChild, int dragLengthY) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02004614 if (hasActiveNotifications()) {
Christoph Studerb0183992014-12-22 21:02:26 +01004615 EventLogTags.writeSysuiLockscreenGesture(
4616 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE,
4617 (int) (dragLengthY / mDisplayMetrics.density),
4618 0 /* velocityDp - N/A */);
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004619
4620 // We have notifications, go to locked shade.
4621 goToLockedShade(startingChild);
Chris Wren6abeeb92016-05-26 14:44:38 -04004622 if (startingChild instanceof ExpandableNotificationRow) {
4623 ExpandableNotificationRow row = (ExpandableNotificationRow) startingChild;
4624 row.onExpandedByGesture(true /* drag down is always an open */);
4625 }
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004626 return true;
4627 } else {
4628
4629 // No notifications - abort gesture.
4630 return false;
4631 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02004632 }
4633
4634 @Override
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004635 public void onDragDownReset() {
4636 mStackScroller.setDimmed(true /* dimmed */, true /* animated */);
Selim Cinek177fd432015-11-18 11:53:47 -08004637 mStackScroller.resetScrollPosition();
Jorim Jaggiecbab362014-04-23 16:13:15 +02004638 }
4639
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004640 @Override
Selim Cinek177fd432015-11-18 11:53:47 -08004641 public void onCrossedThreshold(boolean above) {
4642 mStackScroller.setDimmed(!above /* dimmed */, true /* animate */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004643 }
4644
Selim Cinek1408eb52014-06-02 14:45:38 +02004645 @Override
4646 public void onTouchSlopExceeded() {
4647 mStackScroller.removeLongPressCallback();
4648 }
4649
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004650 @Override
4651 public void setEmptyDragAmount(float amount) {
4652 mNotificationPanel.setEmptyDragAmount(amount);
4653 }
4654
Jorim Jaggiecbab362014-04-23 16:13:15 +02004655 /**
4656 * If secure with redaction: Show bouncer, go to unlocked shade.
4657 *
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004658 * <p>If secure without redaction or no security: Go to {@link StatusBarState#SHADE_LOCKED}.</p>
Jorim Jaggiecbab362014-04-23 16:13:15 +02004659 *
4660 * @param expandView The view to expand after going to the shade.
4661 */
4662 public void goToLockedShade(View expandView) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004663 ExpandableNotificationRow row = null;
Jorim Jaggiecbab362014-04-23 16:13:15 +02004664 if (expandView instanceof ExpandableNotificationRow) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004665 row = (ExpandableNotificationRow) expandView;
Selim Cinekcb24ab82016-02-25 12:49:08 -08004666 row.setUserExpanded(true /* userExpanded */, true /* allowChildExpansion */);
Mady Mellorb0a82462016-04-30 17:31:02 -07004667 // Indicate that the group expansion is changing at this time -- this way the group
4668 // and children backgrounds / divider animations will look correct.
4669 row.setGroupExpansionChanging(true);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004670 }
Adrian Roosaee70462014-09-03 16:27:39 +02004671 boolean fullShadeNeedsBouncer = !userAllowsPrivateNotificationsInPublic(mCurrentUserId)
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004672 || !mShowLockscreenNotifications || mFalsingManager.shouldEnforceBouncer();
Adrian Roosaee70462014-09-03 16:27:39 +02004673 if (isLockscreenPublicMode() && fullShadeNeedsBouncer) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02004674 mLeaveOpenOnKeyguardHide = true;
Adrian Roosf37fce52016-12-13 15:12:02 -08004675 showBouncerIfKeyguard();
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004676 mDraggedDownRow = row;
Adrian Roos3aec6382016-02-05 14:19:01 -08004677 mPendingRemoteInputView = null;
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004678 } else {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004679 mNotificationPanel.animateToFullShade(0 /* delay */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004680 setBarState(StatusBarState.SHADE_LOCKED);
Jorim Jaggi98f85302014-08-07 17:45:04 +02004681 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004682 }
4683 }
4684
Selim Cinek570981d2015-12-01 11:37:01 -08004685 @Override
Mady Mellor8e8a69e2016-03-14 12:30:10 -07004686 public void onLockedNotificationImportanceChange(OnDismissAction dismissAction) {
4687 mLeaveOpenOnKeyguardHide = true;
4688 dismissKeyguardThenExecute(dismissAction, true /* afterKeyguardGone */);
4689 }
4690
4691 @Override
Adrian Roos3aec6382016-02-05 14:19:01 -08004692 protected void onLockedRemoteInput(ExpandableNotificationRow row, View clicked) {
4693 mLeaveOpenOnKeyguardHide = true;
4694 showBouncer();
4695 mPendingRemoteInputView = clicked;
4696 }
4697
4698 @Override
Ricky Waicd35def2016-05-03 11:07:07 +01004699 protected boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender,
4700 String notificationKey) {
4701 // Clear pending remote view, as we do not want to trigger pending remote input view when
4702 // it's called by other code
4703 mPendingWorkRemoteInputView = null;
4704 return super.startWorkChallengeIfNecessary(userId, intendSender, notificationKey);
4705 }
4706
4707 @Override
4708 protected void onLockedWorkRemoteInput(int userId, ExpandableNotificationRow row,
4709 View clicked) {
4710 // Collapse notification and show work challenge
4711 animateCollapsePanels();
4712 startWorkChallengeIfNecessary(userId, null, null);
4713 // Add pending remote input view after starting work challenge, as starting work challenge
4714 // will clear all previous pending review view
4715 mPendingWorkRemoteInputView = clicked;
4716 }
4717
4718 @Override
4719 protected void onWorkChallengeUnlocked() {
4720 if (mPendingWorkRemoteInputView != null) {
4721 final View pendingWorkRemoteInputView = mPendingWorkRemoteInputView;
4722 // Expand notification panel and the notification row, then click on remote input view
4723 final Runnable clickPendingViewRunnable = new Runnable() {
4724 @Override
4725 public void run() {
4726 if (mPendingWorkRemoteInputView != null) {
4727 final View pendingWorkRemoteInputView = mPendingWorkRemoteInputView;
4728 ViewParent p = pendingWorkRemoteInputView.getParent();
4729 while (p != null) {
4730 if (p instanceof ExpandableNotificationRow) {
4731 final ExpandableNotificationRow row = (ExpandableNotificationRow) p;
4732 ViewParent viewParent = row.getParent();
4733 if (viewParent instanceof NotificationStackScrollLayout) {
4734 final NotificationStackScrollLayout scrollLayout =
4735 (NotificationStackScrollLayout) viewParent;
4736 row.makeActionsVisibile();
4737 row.post(new Runnable() {
4738 @Override
4739 public void run() {
4740 final Runnable finishScrollingCallback = new Runnable()
4741 {
4742 @Override
4743 public void run() {
4744 mPendingWorkRemoteInputView.callOnClick();
4745 mPendingWorkRemoteInputView = null;
4746 scrollLayout.setFinishScrollingCallback(null);
4747 }
4748 };
4749 if (scrollLayout.scrollTo(row)) {
4750 // It scrolls! So call it when it's finished.
4751 scrollLayout.setFinishScrollingCallback(
4752 finishScrollingCallback);
4753 } else {
4754 // It does not scroll, so call it now!
4755 finishScrollingCallback.run();
4756 }
4757 }
4758 });
4759 }
4760 break;
4761 }
4762 p = p.getParent();
4763 }
4764 }
4765 }
4766 };
4767 mNotificationPanel.getViewTreeObserver().addOnGlobalLayoutListener(
4768 new ViewTreeObserver.OnGlobalLayoutListener() {
4769 @Override
4770 public void onGlobalLayout() {
4771 if (mNotificationPanel.mStatusBar.getStatusBarWindow()
4772 .getHeight() != mNotificationPanel.mStatusBar
4773 .getStatusBarHeight()) {
4774 mNotificationPanel.getViewTreeObserver()
4775 .removeOnGlobalLayoutListener(this);
4776 mNotificationPanel.post(clickPendingViewRunnable);
4777 }
4778 }
4779 });
4780 instantExpandNotificationsPanel();
4781 }
4782 }
4783
4784 @Override
Selim Cinek31aada42015-12-18 17:51:15 -08004785 public void onExpandClicked(Entry clickedEntry, boolean nowExpanded) {
4786 mHeadsUpManager.setExpanded(clickedEntry, nowExpanded);
Selim Cinek570981d2015-12-01 11:37:01 -08004787 if (mState == StatusBarState.KEYGUARD && nowExpanded) {
Selim Cinek31aada42015-12-18 17:51:15 -08004788 goToLockedShade(clickedEntry.row);
Selim Cinek570981d2015-12-01 11:37:01 -08004789 }
4790 }
4791
Adrian Roos5a46cd32014-04-03 16:51:58 +02004792 /**
Jorim Jaggi6539a832014-06-03 23:33:09 +02004793 * Goes back to the keyguard after hanging around in {@link StatusBarState#SHADE_LOCKED}.
4794 */
4795 public void goToKeyguard() {
4796 if (mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekd9acca52014-09-01 22:33:25 +02004797 mStackScroller.onGoToKeyguard();
Jorim Jaggi6539a832014-06-03 23:33:09 +02004798 setBarState(StatusBarState.KEYGUARD);
Jorim Jaggi98f85302014-08-07 17:45:04 +02004799 updateKeyguardState(false /* goingToFullShade */, true /* fromShadeLocked*/);
Jorim Jaggi6539a832014-06-03 23:33:09 +02004800 }
4801 }
4802
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004803 public long getKeyguardFadingAwayDelay() {
4804 return mKeyguardFadingAwayDelay;
4805 }
4806
4807 public long getKeyguardFadingAwayDuration() {
4808 return mKeyguardFadingAwayDuration;
4809 }
4810
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004811 @Override
4812 public void setBouncerShowing(boolean bouncerShowing) {
4813 super.setBouncerShowing(bouncerShowing);
Adrian Roosd0b2f7d2015-04-29 13:36:12 -07004814 mStatusBarView.setBouncerShowing(bouncerShowing);
Adrian Roos316bf542016-08-23 17:53:07 +02004815 recomputeDisableFlags(true /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004816 }
4817
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004818 public void onStartedGoingToSleep() {
4819 mStartedGoingToSleep = true;
4820 }
4821
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004822 public void onFinishedGoingToSleep() {
Selim Cinek372d1bd2015-08-14 13:19:37 -07004823 mNotificationPanel.onAffordanceLaunchEnded();
4824 releaseGestureWakeLock();
4825 mLaunchCameraOnScreenTurningOn = false;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004826 mStartedGoingToSleep = false;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004827 mDeviceInteractive = false;
4828 mWakeUpComingFromTouch = false;
4829 mWakeUpTouchLocation = null;
Jorim Jaggi75c95042014-05-16 19:09:59 +02004830 mStackScroller.setAnimationsEnabled(false);
Selim Cinekadd95262016-12-06 14:34:47 -08004831 mVisualStabilityManager.setScreenOn(false);
Christoph Studere8e28652014-10-29 17:27:53 +01004832 updateVisibleToUser();
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004833 if (mLaunchCameraOnFinishedGoingToSleep) {
4834 mLaunchCameraOnFinishedGoingToSleep = false;
4835
4836 // This gets executed before we will show Keyguard, so post it in order that the state
4837 // is correct.
4838 mHandler.post(new Runnable() {
4839 @Override
4840 public void run() {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004841 onCameraLaunchGestureDetected(mLastCameraLaunchSource);
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004842 }
4843 });
4844 }
Jorim Jaggi75c95042014-05-16 19:09:59 +02004845 }
4846
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004847 public void onStartedWakingUp() {
4848 mDeviceInteractive = true;
Jorim Jaggi75c95042014-05-16 19:09:59 +02004849 mStackScroller.setAnimationsEnabled(true);
Selim Cinekadd95262016-12-06 14:34:47 -08004850 mVisualStabilityManager.setScreenOn(true);
Jorim Jaggid41083a2014-09-12 02:54:40 +02004851 mNotificationPanel.setTouchDisabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01004852 updateVisibleToUser();
Jorim Jaggi75c95042014-05-16 19:09:59 +02004853 }
John Spurlockd08f91f2014-05-23 11:00:34 -04004854
Jorim Jaggi93739112015-08-13 15:53:14 -07004855 public void onScreenTurningOn() {
Selim Cinek1b6f8192015-09-03 16:01:53 -07004856 mScreenTurningOn = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004857 mFalsingManager.onScreenTurningOn();
Jorim Jaggi93739112015-08-13 15:53:14 -07004858 mNotificationPanel.onScreenTurningOn();
Selim Cinek372d1bd2015-08-14 13:19:37 -07004859 if (mLaunchCameraOnScreenTurningOn) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004860 mNotificationPanel.launchCamera(false, mLastCameraLaunchSource);
Selim Cinek372d1bd2015-08-14 13:19:37 -07004861 mLaunchCameraOnScreenTurningOn = false;
4862 }
Jorim Jaggi93739112015-08-13 15:53:14 -07004863 }
4864
Selim Cinek69ff8af2015-08-25 19:03:48 -07004865 private void vibrateForCameraGesture() {
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004866 // Make sure to pass -1 for repeat so VibratorService doesn't stop us when going to sleep.
Jorim Jaggi8ba1cb32016-06-24 17:33:01 -07004867 mVibrator.vibrate(new long[]{0, 400}, -1 /* repeat */);
Selim Cinek69ff8af2015-08-25 19:03:48 -07004868 }
4869
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004870 public void onScreenTurnedOn() {
Selim Cinek1b6f8192015-09-03 16:01:53 -07004871 mScreenTurningOn = false;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004872 mDozeScrimController.onScreenTurnedOn();
4873 }
4874
Jason Monk815e0572014-08-12 17:26:36 -04004875 /**
Jorim Jaggi4e723e62016-12-14 11:02:39 -08004876 * This handles long-press of both back and recents. They are
4877 * handled together to capture them both being long-pressed
4878 * at the same time to exit screen pinning (lock task).
4879 *
4880 * When accessibility mode is on, only a long-press from recents
4881 * is required to exit.
4882 *
4883 * In all other circumstances we try to pass through long-press events
4884 * for Back, so that apps can still use it. Which can be from two things.
4885 * 1) Not currently in screen pinning (lock task).
4886 * 2) Back is long-pressed without recents.
Jason Monk815e0572014-08-12 17:26:36 -04004887 */
Jorim Jaggi4e723e62016-12-14 11:02:39 -08004888 private boolean handleLongPressBackRecents(View v) {
Jason Monk62515be2014-05-21 16:06:19 -04004889 try {
Jorim Jaggi4e723e62016-12-14 11:02:39 -08004890 boolean sendBackLongPress = false;
Jason Monk62515be2014-05-21 16:06:19 -04004891 IActivityManager activityManager = ActivityManagerNative.getDefault();
Jorim Jaggi4e723e62016-12-14 11:02:39 -08004892 boolean touchExplorationEnabled = mAccessibilityManager.isTouchExplorationEnabled();
4893 boolean inLockTaskMode = activityManager.isInLockTaskMode();
4894 if (inLockTaskMode && !touchExplorationEnabled) {
4895 long time = System.currentTimeMillis();
4896 // If we recently long-pressed the other button then they were
4897 // long-pressed 'together'
4898 if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERENCE) {
4899 activityManager.stopLockTaskMode();
4900 // When exiting refresh disabled flags.
4901 mNavigationBarView.setDisabledFlags(mDisabled1, true);
4902 return true;
4903 } else if ((v.getId() == R.id.back)
4904 && !mNavigationBarView.getRecentsButton().getCurrentView().isPressed()) {
4905 // If we aren't pressing recents right now then they presses
4906 // won't be together, so send the standard long-press action.
4907 sendBackLongPress = true;
4908 }
4909 mLastLockToAppLongPress = time;
4910 } else {
4911 // If this is back still need to handle sending the long-press event.
4912 if (v.getId() == R.id.back) {
4913 sendBackLongPress = true;
4914 } else if (touchExplorationEnabled && inLockTaskMode) {
4915 // When in accessibility mode a long press that is recents (not back)
4916 // should stop lock task.
4917 activityManager.stopLockTaskMode();
4918 // When exiting refresh disabled flags.
4919 mNavigationBarView.setDisabledFlags(mDisabled1, true);
4920 return true;
4921 } else if (v.getId() == R.id.recent_apps) {
4922 return handleLongPressRecents();
4923 }
4924 }
4925 if (sendBackLongPress) {
4926 KeyButtonView keyButtonView = (KeyButtonView) v;
4927 keyButtonView.sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
4928 keyButtonView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
Jorim Jaggi75b25972015-10-21 14:51:10 +02004929 return true;
Jason Monk62515be2014-05-21 16:06:19 -04004930 }
4931 } catch (RemoteException e) {
Jason Monk815e0572014-08-12 17:26:36 -04004932 Log.d(TAG, "Unable to reach activity manager", e);
Jason Monk62515be2014-05-21 16:06:19 -04004933 }
Jorim Jaggi75b25972015-10-21 14:51:10 +02004934 return false;
Jason Monk62515be2014-05-21 16:06:19 -04004935 }
4936
Jorim Jaggi4e723e62016-12-14 11:02:39 -08004937 private boolean handleLongPressRecents() {
4938 if (mRecents == null || !ActivityManager.supportsMultiWindow()
4939 || !getComponent(Divider.class).getView().getSnapAlgorithm()
4940 .isSplitScreenFeasible()) {
4941 return false;
4942 }
4943
4944 toggleSplitScreenMode(MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS,
4945 MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS);
4946 return true;
4947 }
4948
Jason Monk5565cb42014-09-12 10:59:21 -04004949 @Override
Andrii Kulian0f051f52016-04-14 00:41:51 -07004950 public void showScreenPinningRequest(int taskId) {
Jason Monk18f99d92014-09-11 13:36:42 -04004951 if (mKeyguardMonitor.isShowing()) {
4952 // Don't allow apps to trigger this from keyguard.
4953 return;
4954 }
4955 // Show screen pinning request, since this comes from an app, show 'no thanks', button.
Andrii Kulian0f051f52016-04-14 00:41:51 -07004956 showScreenPinningRequest(taskId, true);
Jason Monk18f99d92014-09-11 13:36:42 -04004957 }
4958
Andrii Kulian0f051f52016-04-14 00:41:51 -07004959 public void showScreenPinningRequest(int taskId, boolean allowCancel) {
4960 mScreenPinningRequest.showPrompt(taskId, allowCancel);
Jason Monk5565cb42014-09-12 10:59:21 -04004961 }
4962
Christoph Studerc8db24b2014-07-25 17:50:30 +02004963 public boolean hasActiveNotifications() {
4964 return !mNotificationData.getActiveNotifications().isEmpty();
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004965 }
4966
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01004967 public void wakeUpIfDozing(long time, MotionEvent event) {
Jorim Jaggi048af1f2014-11-11 22:51:10 +01004968 if (mDozing && mDozeScrimController.isPulsing()) {
John Spurlock8b12f222014-09-09 11:54:11 -04004969 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
Dianne Hackborn280a64e2015-07-13 14:48:08 -07004970 pm.wakeUp(time, "com.android.systemui:NODOZE");
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004971 mWakeUpComingFromTouch = true;
4972 mWakeUpTouchLocation = new PointF(event.getX(), event.getY());
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01004973 mNotificationPanel.setTouchDisabled(false);
Jorim Jaggi0d210f62015-07-10 14:24:44 -07004974 mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004975 mFalsingManager.onScreenOnFromTouch();
John Spurlock8b12f222014-09-09 11:54:11 -04004976 }
4977 }
4978
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004979 @Override
4980 public void appTransitionPending() {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004981
4982 // Use own timings when Keyguard is going away, see keyguardGoingAway and
4983 // setKeyguardFadingAway
4984 if (!mKeyguardFadingAway) {
4985 mIconController.appTransitionPending();
4986 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004987 }
4988
4989 @Override
4990 public void appTransitionCancelled() {
4991 mIconController.appTransitionCancelled();
Jorim Jaggi2adba072016-03-03 13:43:39 +01004992 EventBus.getDefault().send(new AppTransitionFinishedEvent());
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004993 }
4994
4995 @Override
4996 public void appTransitionStarting(long startTime, long duration) {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004997
4998 // Use own timings when Keyguard is going away, see keyguardGoingAway and
Adrian Roos46df1ca2015-09-11 12:38:43 -07004999 // setKeyguardFadingAway.
5000 if (!mKeyguardGoingAway) {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01005001 mIconController.appTransitionStarting(startTime, duration);
5002 }
Kenny Guy3094d4a2015-04-01 19:14:10 +01005003 if (mIconPolicy != null) {
5004 mIconPolicy.appTransitionStarting(startTime, duration);
5005 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01005006 }
5007
Selim Cinek372d1bd2015-08-14 13:19:37 -07005008 @Override
Jorim Jaggi2adba072016-03-03 13:43:39 +01005009 public void appTransitionFinished() {
5010 EventBus.getDefault().send(new AppTransitionFinishedEvent());
5011 }
5012
5013 @Override
Jorim Jaggi40aa8812015-09-23 12:59:22 -07005014 public void onCameraLaunchGestureDetected(int source) {
5015 mLastCameraLaunchSource = source;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07005016 if (mStartedGoingToSleep) {
5017 mLaunchCameraOnFinishedGoingToSleep = true;
5018 return;
5019 }
Zhentao Sun04f97402015-08-26 17:37:30 -07005020 if (!mNotificationPanel.canCameraGestureBeLaunched(
5021 mStatusBarKeyguardViewManager.isShowing() && mExpandedVisible)) {
Selim Cinek372d1bd2015-08-14 13:19:37 -07005022 return;
5023 }
5024 if (!mDeviceInteractive) {
5025 PowerManager pm = mContext.getSystemService(PowerManager.class);
5026 pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:CAMERA_GESTURE");
5027 mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
5028 }
Selim Cinek69ff8af2015-08-25 19:03:48 -07005029 vibrateForCameraGesture();
Selim Cinek372d1bd2015-08-14 13:19:37 -07005030 if (!mStatusBarKeyguardViewManager.isShowing()) {
5031 startActivity(KeyguardBottomAreaView.INSECURE_CAMERA_INTENT,
5032 true /* dismissShade */);
5033 } else {
5034 if (!mDeviceInteractive) {
5035 // Avoid flickering of the scrim when we instant launch the camera and the bouncer
5036 // comes on.
5037 mScrimController.dontAnimateBouncerChangesUntilNextFrame();
5038 mGestureWakeLock.acquire(LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
5039 }
Selim Cinek1b6f8192015-09-03 16:01:53 -07005040 if (mScreenTurningOn || mStatusBarKeyguardViewManager.isScreenTurnedOn()) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07005041 mNotificationPanel.launchCamera(mDeviceInteractive /* animate */, source);
Selim Cinek372d1bd2015-08-14 13:19:37 -07005042 } else {
5043 // We need to defer the camera launch until the screen comes on, since otherwise
5044 // we will dismiss us too early since we are waiting on an activity to be drawn and
5045 // incorrectly get notified because of the screen on event (which resumes and pauses
5046 // some activities)
5047 mLaunchCameraOnScreenTurningOn = true;
5048 }
5049 }
5050 }
5051
Jaewan Kimc552b042016-01-18 16:08:45 +09005052 @Override
Jaewan Kimf0fd2182016-04-20 21:17:58 +09005053 public void showTvPictureInPictureMenu() {
Jaewan Kimc552b042016-01-18 16:08:45 +09005054 // no-op.
5055 }
5056
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07005057 public void notifyFpAuthModeChanged() {
5058 updateDozing();
5059 }
5060
Jorim Jaggi83969702015-06-05 14:59:24 -07005061 private void updateDozing() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07005062 Trace.beginSection("PhoneStatusBar#updateDozing");
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07005063 // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
5064 mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD
5065 || mFingerprintUnlockController.getMode()
5066 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
Jorim Jaggi83969702015-06-05 14:59:24 -07005067 updateDozingState();
Nick Desaulniers1d396752016-07-25 15:05:33 -07005068 Trace.endSection();
Jorim Jaggi83969702015-06-05 14:59:24 -07005069 }
5070
John Spurlockbf370992014-06-17 13:58:31 -04005071 private final class ShadeUpdates {
5072 private final ArraySet<String> mVisibleNotifications = new ArraySet<String>();
5073 private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>();
5074
5075 public void check() {
5076 mNewVisibleNotifications.clear();
Christoph Studerc8db24b2014-07-25 17:50:30 +02005077 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
5078 for (int i = 0; i < activeNotifications.size(); i++) {
5079 final Entry entry = activeNotifications.get(i);
John Spurlockbf370992014-06-17 13:58:31 -04005080 final boolean visible = entry.row != null
5081 && entry.row.getVisibility() == View.VISIBLE;
5082 if (visible) {
5083 mNewVisibleNotifications.add(entry.key + entry.notification.getPostTime());
5084 }
5085 }
5086 final boolean updates = !mVisibleNotifications.containsAll(mNewVisibleNotifications);
5087 mVisibleNotifications.clear();
Dianne Hackborn497175b2014-07-01 12:56:08 -07005088 mVisibleNotifications.addAll(mNewVisibleNotifications);
John Spurlockbf370992014-06-17 13:58:31 -04005089
5090 // We have new notifications
5091 if (updates && mDozeServiceHost != null) {
5092 mDozeServiceHost.fireNewNotifications();
5093 }
5094 }
5095 }
5096
Selim Cinek99415392016-09-09 14:58:41 -07005097 private final class DozeServiceHost implements DozeHost {
John Spurlockbf370992014-06-17 13:58:31 -04005098 // Amount of time to allow to update the time shown on the screen before releasing
5099 // the wakelock. This timeout is design to compensate for the fact that we don't
5100 // currently have a way to know when time display contents have actually been
5101 // refreshed once we've finished rendering a new frame.
5102 private static final long PROCESSING_TIME = 500;
5103
5104 private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
5105 private final H mHandler = new H();
5106
Christoph Studer1f32c652014-11-26 15:32:20 +01005107 // Keeps the last reported state by fireNotificationLight.
5108 private boolean mNotificationLightOn;
5109
John Spurlockc6eed842014-08-25 12:19:41 -04005110 @Override
5111 public String toString() {
Jeff Brown4d69e222014-09-18 15:27:50 -07005112 return "PSB.DozeServiceHost[mCallbacks=" + mCallbacks.size() + "]";
John Spurlock8b12f222014-09-09 11:54:11 -04005113 }
5114
John Spurlockd96179e2014-08-21 16:43:45 -04005115 public void firePowerSaveChanged(boolean active) {
5116 for (Callback callback : mCallbacks) {
5117 callback.onPowerSaveChanged(active);
5118 }
5119 }
5120
John Spurlockcad57682014-07-26 17:09:56 -04005121 public void fireBuzzBeepBlinked() {
5122 for (Callback callback : mCallbacks) {
5123 callback.onBuzzBeepBlinked();
5124 }
5125 }
5126
John Spurlockcb566aa2014-08-03 22:58:28 -04005127 public void fireNotificationLight(boolean on) {
Christoph Studer1f32c652014-11-26 15:32:20 +01005128 mNotificationLightOn = on;
John Spurlockcb566aa2014-08-03 22:58:28 -04005129 for (Callback callback : mCallbacks) {
5130 callback.onNotificationLight(on);
5131 }
5132 }
5133
John Spurlockbf370992014-06-17 13:58:31 -04005134 public void fireNewNotifications() {
5135 for (Callback callback : mCallbacks) {
5136 callback.onNewNotifications();
5137 }
5138 }
5139
5140 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07005141 public void addCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04005142 mCallbacks.add(callback);
5143 }
5144
5145 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07005146 public void removeCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04005147 mCallbacks.remove(callback);
5148 }
5149
5150 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07005151 public void startDozing(@NonNull Runnable ready) {
5152 mHandler.obtainMessage(H.MSG_START_DOZING, ready).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04005153 }
5154
5155 @Override
John Spurlockeab28e62014-11-29 11:33:49 -05005156 public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
5157 mHandler.obtainMessage(H.MSG_PULSE_WHILE_DOZING, reason, 0, callback).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04005158 }
5159
5160 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07005161 public void stopDozing() {
5162 mHandler.obtainMessage(H.MSG_STOP_DOZING).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04005163 }
5164
John Spurlockd96179e2014-08-21 16:43:45 -04005165 @Override
5166 public boolean isPowerSaveActive() {
5167 return mBatteryController != null && mBatteryController.isPowerSave();
5168 }
5169
Christoph Studer1f32c652014-11-26 15:32:20 +01005170 @Override
Jorim Jaggi007f0e82015-08-14 13:56:01 -07005171 public boolean isPulsingBlocked() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07005172 return mFingerprintUnlockController.getMode()
5173 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
Jorim Jaggi007f0e82015-08-14 13:56:01 -07005174 }
5175
5176 @Override
Christoph Studer1f32c652014-11-26 15:32:20 +01005177 public boolean isNotificationLightOn() {
5178 return mNotificationLightOn;
5179 }
5180
Jeff Brown4d69e222014-09-18 15:27:50 -07005181 private void handleStartDozing(@NonNull Runnable ready) {
Jorim Jaggi83969702015-06-05 14:59:24 -07005182 if (!mDozingRequested) {
5183 mDozingRequested = true;
John Spurlock813552c2014-09-19 08:30:21 -04005184 DozeLog.traceDozing(mContext, mDozing);
Jorim Jaggi83969702015-06-05 14:59:24 -07005185 updateDozing();
John Spurlockbf370992014-06-17 13:58:31 -04005186 }
Jeff Brown4d69e222014-09-18 15:27:50 -07005187 ready.run();
John Spurlockbf370992014-06-17 13:58:31 -04005188 }
5189
John Spurlockeab28e62014-11-29 11:33:49 -05005190 private void handlePulseWhileDozing(@NonNull PulseCallback callback, int reason) {
Selim Cinekcd5b22f2016-03-08 16:15:41 -08005191 mDozeScrimController.pulse(new PulseCallback() {
5192
5193 @Override
5194 public void onPulseStarted() {
5195 callback.onPulseStarted();
5196 mStackScroller.setPulsing(true);
5197 }
5198
5199 @Override
5200 public void onPulseFinished() {
5201 callback.onPulseFinished();
5202 mStackScroller.setPulsing(false);
5203 }
5204 }, reason);
John Spurlockbf370992014-06-17 13:58:31 -04005205 }
5206
Jeff Brown4d69e222014-09-18 15:27:50 -07005207 private void handleStopDozing() {
Jorim Jaggi83969702015-06-05 14:59:24 -07005208 if (mDozingRequested) {
5209 mDozingRequested = false;
John Spurlock813552c2014-09-19 08:30:21 -04005210 DozeLog.traceDozing(mContext, mDozing);
Jorim Jaggi83969702015-06-05 14:59:24 -07005211 updateDozing();
John Spurlockbf370992014-06-17 13:58:31 -04005212 }
5213 }
5214
5215 private final class H extends Handler {
Jeff Brown4d69e222014-09-18 15:27:50 -07005216 private static final int MSG_START_DOZING = 1;
5217 private static final int MSG_PULSE_WHILE_DOZING = 2;
5218 private static final int MSG_STOP_DOZING = 3;
John Spurlockbf370992014-06-17 13:58:31 -04005219
5220 @Override
5221 public void handleMessage(Message msg) {
Jeff Brown4d69e222014-09-18 15:27:50 -07005222 switch (msg.what) {
5223 case MSG_START_DOZING:
5224 handleStartDozing((Runnable) msg.obj);
5225 break;
5226 case MSG_PULSE_WHILE_DOZING:
John Spurlockeab28e62014-11-29 11:33:49 -05005227 handlePulseWhileDozing((PulseCallback) msg.obj, msg.arg1);
Jeff Brown4d69e222014-09-18 15:27:50 -07005228 break;
5229 case MSG_STOP_DOZING:
5230 handleStopDozing();
5231 break;
John Spurlockbf370992014-06-17 13:58:31 -04005232 }
5233 }
5234 }
5235 }
Romain Guy648342f2012-05-25 10:44:45 -07005236}