blob: e3ce1e27f3e6801edc5d4dd7ceed6c8722ac094a [file] [log] [blame]
Joe Onorato808182d2010-07-09 18:52:06 -04001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Joe Onoratofd52b182010-11-10 18:00:52 -080017package com.android.systemui.statusbar.phone;
Joe Onorato808182d2010-07-09 18:52:06 -040018
Jorim Jaggicff0acb2014-03-31 16:35:15 +020019
Daniel Sandlerd7e96862012-04-26 01:10:29 -040020import android.animation.Animator;
21import android.animation.AnimatorListenerAdapter;
Jeff Brown4d69e222014-09-18 15:27:50 -070022import android.annotation.NonNull;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -070023import android.app.ActivityManager;
Joe Onorato808182d2010-07-09 18:52:06 -040024import android.app.ActivityManagerNative;
Jason Monk62515be2014-05-21 16:06:19 -040025import android.app.IActivityManager;
Joe Onorato808182d2010-07-09 18:52:06 -040026import android.app.Notification;
27import android.app.PendingIntent;
Joe Onorato808182d2010-07-09 18:52:06 -040028import android.app.StatusBarManager;
29import android.content.BroadcastReceiver;
Jorim Jaggi786afcb2014-09-25 02:41:29 +020030import android.content.ComponentCallbacks2;
Jason Monk7e53f202016-01-28 10:40:20 -050031import android.content.ComponentName;
Joe Onorato808182d2010-07-09 18:52:06 -040032import android.content.Context;
33import android.content.Intent;
34import android.content.IntentFilter;
Ricky Waicd35def2016-05-03 11:07:07 +010035import android.content.IntentSender;
Adrian Roos21d2a252015-06-01 13:59:59 -070036import android.content.pm.IPackageManager;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -070037import android.content.pm.PackageManager;
Tony Mak92c989d2016-04-19 14:02:44 +010038import android.content.pm.UserInfo;
Daniel Sandler777dcde2013-09-30 10:21:45 -040039import android.content.res.Configuration;
Michael Jurka7f2668c2012-03-27 07:49:52 -070040import android.content.res.Resources;
John Spurlock919adac2012-10-02 16:41:12 -040041import android.database.ContentObserver;
Dan Sandler16128f42014-05-21 12:48:22 -040042import android.graphics.Bitmap;
Romain Guy648342f2012-05-25 10:44:45 -070043import android.graphics.Canvas;
44import android.graphics.ColorFilter;
Joe Onorato808182d2010-07-09 18:52:06 -040045import android.graphics.PixelFormat;
Daniel Sandlere680f542012-09-28 12:22:27 -040046import android.graphics.Point;
Jorim Jaggi2a5e4522014-11-24 21:45:20 +010047import android.graphics.PointF;
Romain Guy648342f2012-05-25 10:44:45 -070048import android.graphics.PorterDuff;
Selim Cineka0fad3b2014-09-19 17:20:05 +020049import android.graphics.PorterDuffXfermode;
Joe Onorato808182d2010-07-09 18:52:06 -040050import android.graphics.Rect;
Adrian Roos3b777cb2016-04-14 12:04:28 -070051import android.graphics.drawable.BitmapDrawable;
Dan Sandler16128f42014-05-21 12:48:22 -040052import android.graphics.drawable.ColorDrawable;
Romain Guy648342f2012-05-25 10:44:45 -070053import android.graphics.drawable.Drawable;
Michael Jurka7f2668c2012-03-27 07:49:52 -070054import android.inputmethodservice.InputMethodService;
John Spurlock7b414672014-07-18 13:02:39 -040055import android.media.AudioAttributes;
Dan Sandler16128f42014-05-21 12:48:22 -040056import android.media.MediaMetadata;
57import android.media.session.MediaController;
58import android.media.session.MediaSession;
59import android.media.session.MediaSessionManager;
60import android.media.session.PlaybackState;
Selim Cinekbaa23272014-07-08 18:01:07 +020061import android.os.AsyncTask;
John Spurlock3c875662013-08-31 15:07:25 -040062import android.os.Bundle;
John Spurlock919adac2012-10-02 16:41:12 -040063import android.os.Handler;
Jason Monk4ae97d32014-12-17 10:14:33 -050064import android.os.HandlerThread;
Joe Onorato808182d2010-07-09 18:52:06 -040065import android.os.IBinder;
Joe Onorato808182d2010-07-09 18:52:06 -040066import android.os.Message;
John Spurlock56d007b2013-10-28 18:40:56 -040067import android.os.PowerManager;
Jason Monk4ae97d32014-12-17 10:14:33 -050068import android.os.Process;
Michael Jurka7f2668c2012-03-27 07:49:52 -070069import android.os.RemoteException;
Adrian Roos21d2a252015-06-01 13:59:59 -070070import android.os.ServiceManager;
Joe Onorato808182d2010-07-09 18:52:06 -040071import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070072import android.os.UserHandle;
Adrian Roos2b154a92014-11-17 15:18:39 +010073import android.os.UserManager;
Selim Cinek69ff8af2015-08-25 19:03:48 -070074import android.os.Vibrator;
Daniel Sandlerd3090562011-08-09 00:28:44 -040075import android.provider.Settings;
Chris Wren3ad4e3a2014-09-02 17:23:51 -040076import android.service.notification.NotificationListenerService;
Christoph Studerd0694b62014-06-04 16:36:01 +020077import android.service.notification.NotificationListenerService.RankingMap;
John Spurlockde84f0e2013-06-12 12:41:00 -040078import android.service.notification.StatusBarNotification;
Christoph Studer92b389d2014-04-01 18:44:40 +020079import android.util.ArraySet;
Daniel Sandler36412a72011-08-04 09:35:13 -040080import android.util.DisplayMetrics;
Chris Wren64161cc2012-12-17 16:49:30 -050081import android.util.EventLog;
Joe Onorato808182d2010-07-09 18:52:06 -040082import android.util.Log;
83import android.view.Display;
Jorim Jaggidf993512014-05-13 23:06:35 +020084import android.view.KeyEvent;
Jorim Jaggid4a57442014-04-10 02:45:55 +020085import android.view.LayoutInflater;
Joe Onorato808182d2010-07-09 18:52:06 -040086import android.view.MotionEvent;
Chris Craik2507c342015-05-04 14:36:49 -070087import android.view.ThreadedRenderer;
Joe Onorato808182d2010-07-09 18:52:06 -040088import android.view.View;
Xiyuan Xia1b30f792016-01-06 08:50:30 -080089import android.view.ViewGroup;
Jim Millerf2a16b22011-07-06 17:32:48 -070090import android.view.ViewGroup.LayoutParams;
Selim Cinek3e7592d2016-04-11 09:35:54 +080091import android.view.ViewParent;
Dan Sandler44c0dfd2014-06-09 11:26:16 -040092import android.view.ViewStub;
Ricky Waicd35def2016-05-03 11:07:07 +010093import android.view.ViewTreeObserver;
Joe Onorato808182d2010-07-09 18:52:06 -040094import android.view.WindowManager;
Jorim Jaggi786afcb2014-09-25 02:41:29 +020095import android.view.WindowManagerGlobal;
Daniel Sandlerd7e96862012-04-26 01:10:29 -040096import android.view.animation.AccelerateInterpolator;
Jorim Jaggib13d36d2014-06-06 18:03:52 +020097import android.view.animation.Interpolator;
Dan Sandler16128f42014-05-21 12:48:22 -040098import android.widget.ImageView;
Joe Onorato808182d2010-07-09 18:52:06 -040099import android.widget.TextView;
Chris Wren9763d422015-04-30 15:24:05 -0400100import com.android.internal.logging.MetricsLogger;
Chris Wrenf6e9228b2016-01-26 18:04:35 -0500101import com.android.internal.logging.MetricsProto.MetricsEvent;
Chris Wrend1dbc922015-06-19 17:51:16 -0400102import com.android.internal.statusbar.NotificationVisibility;
Joe Onorato808182d2010-07-09 18:52:06 -0400103import com.android.internal.statusbar.StatusBarIcon;
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +0100104import com.android.keyguard.KeyguardHostView.OnDismissAction;
Jason Monkab525272015-07-13 17:02:49 -0400105import com.android.keyguard.KeyguardUpdateMonitor;
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700106import com.android.keyguard.KeyguardUpdateMonitorCallback;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200107import com.android.keyguard.ViewMediatorCallback;
Clara Bayarri9b1fdff2016-04-21 14:28:47 +0100108import com.android.systemui.AutoReinflateContainer;
109import com.android.systemui.AutoReinflateContainer.InflateListener;
Jorim Jaggi708f7722014-08-20 17:30:38 +0200110import com.android.systemui.BatteryMeterView;
John Spurlock3c875662013-08-31 15:07:25 -0400111import com.android.systemui.DemoMode;
Christoph Studerb0183992014-12-22 21:02:26 +0100112import com.android.systemui.EventLogConstants;
Chris Wren64161cc2012-12-17 16:49:30 -0500113import com.android.systemui.EventLogTags;
Winsonc0d70582016-01-29 10:24:39 -0800114import com.android.systemui.Interpolators;
Andrew Flynn82862572015-04-01 14:22:37 -0400115import com.android.systemui.Prefs;
Joe Onorato808182d2010-07-09 18:52:06 -0400116import com.android.systemui.R;
Xiaohui Chen5da71352016-02-22 10:04:41 -0800117import com.android.systemui.SystemUIFactory;
Selim Cineke70d6532015-04-24 16:46:13 -0700118import com.android.systemui.assist.AssistManager;
Adrian Roos401caae2016-03-04 13:35:21 -0800119import com.android.systemui.classifier.FalsingLog;
Selim Cinek5f71bee2015-11-18 10:25:23 -0800120import com.android.systemui.classifier.FalsingManager;
Jeff Brown4d69e222014-09-18 15:27:50 -0700121import com.android.systemui.doze.DozeHost;
John Spurlock813552c2014-09-19 08:30:21 -0400122import com.android.systemui.doze.DozeLog;
Jorim Jaggicff0acb2014-03-31 16:35:15 +0200123import com.android.systemui.keyguard.KeyguardViewMediator;
Jason Monk162011e2016-02-19 08:11:55 -0500124import com.android.systemui.qs.QSContainer;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400125import com.android.systemui.qs.QSPanel;
Jorim Jaggid61f2272014-12-19 20:35:35 +0100126import com.android.systemui.recents.ScreenPinningRequest;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800127import com.android.systemui.recents.events.EventBus;
Jorim Jaggi2adba072016-03-03 13:43:39 +0100128import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800129import com.android.systemui.recents.events.activity.UndockingTaskEvent;
Jorim Jaggidd98d412015-11-18 15:57:38 -0800130import com.android.systemui.stackdivider.Divider;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800131import com.android.systemui.stackdivider.WindowManagerProxy;
Selim Cineka32ab602014-06-11 15:06:01 +0200132import com.android.systemui.statusbar.ActivatableNotificationView;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200133import com.android.systemui.statusbar.BackDropView;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500134import com.android.systemui.statusbar.BaseStatusBar;
Michael Jurkaa600fd92012-06-25 15:57:05 -0700135import com.android.systemui.statusbar.CommandQueue;
Dan Sandlereceda3d2014-07-21 15:35:01 -0400136import com.android.systemui.statusbar.DismissView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200137import com.android.systemui.statusbar.DragDownHelper;
Jorim Jaggia2052ea2014-08-05 16:22:30 +0200138import com.android.systemui.statusbar.EmptyShadeView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200139import com.android.systemui.statusbar.ExpandableNotificationRow;
Daniel Sandler33805342012-07-23 15:45:12 -0400140import com.android.systemui.statusbar.GestureRecorder;
Andrei Stingaceanuf86bc972016-04-12 15:29:25 +0100141import com.android.systemui.statusbar.KeyboardShortcuts;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200142import com.android.systemui.statusbar.KeyguardIndicationController;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700143import com.android.systemui.statusbar.NotificationData;
Daniel Sandler58b173b2012-05-03 11:25:29 -0400144import com.android.systemui.statusbar.NotificationData.Entry;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200145import com.android.systemui.statusbar.NotificationOverflowContainer;
Adrian Roos1c0ca502015-10-07 12:20:42 -0700146import com.android.systemui.statusbar.RemoteInputController;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200147import com.android.systemui.statusbar.ScrimView;
Christian Robertson2e347422011-08-11 14:01:04 -0700148import com.android.systemui.statusbar.SignalClusterView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200149import com.android.systemui.statusbar.StatusBarState;
Christoph Studer2231c6e2014-12-19 12:40:13 +0100150import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200151import com.android.systemui.statusbar.policy.AccessibilityController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400152import com.android.systemui.statusbar.policy.BatteryController;
John Spurlock0ff62e02014-07-22 16:15:08 -0400153import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700154import com.android.systemui.statusbar.policy.BatteryControllerImpl;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400155import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200156import com.android.systemui.statusbar.policy.BrightnessMirrorController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400157import com.android.systemui.statusbar.policy.CastControllerImpl;
Adrian Roosb83777b2014-06-30 15:11:53 +0200158import com.android.systemui.statusbar.policy.FlashlightController;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700159import com.android.systemui.statusbar.policy.HeadsUpManager;
Jason Monk3d5f5512014-07-25 11:17:28 -0400160import com.android.systemui.statusbar.policy.HotspotControllerImpl;
John Spurlock657c62c2014-07-22 12:18:09 -0400161import com.android.systemui.statusbar.policy.KeyguardMonitor;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700162import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400163import com.android.systemui.statusbar.policy.LocationControllerImpl;
164import com.android.systemui.statusbar.policy.NetworkControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400165import com.android.systemui.statusbar.policy.NextAlarmController;
Jorim Jaggi85dc23c2014-09-08 14:42:29 +0200166import com.android.systemui.statusbar.policy.PreviewInflater;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400167import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400168import com.android.systemui.statusbar.policy.SecurityControllerImpl;
169import com.android.systemui.statusbar.policy.UserInfoController;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200170import com.android.systemui.statusbar.policy.UserSwitcherController;
John Spurlock86005342014-05-23 11:58:00 -0400171import com.android.systemui.statusbar.policy.ZenModeController;
Selim Cinek67b22602014-03-10 15:40:16 +0100172import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
Christoph Studer92b389d2014-04-01 18:44:40 +0200173import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
Jorim Jaggi37c11802015-08-18 20:27:54 -0700174import com.android.systemui.statusbar.stack.StackStateAnimator;
Selim Cinekb036ca42015-02-20 15:56:28 +0100175import com.android.systemui.statusbar.stack.StackViewState;
John Spurlock86005342014-05-23 11:58:00 -0400176import com.android.systemui.volume.VolumeComponent;
Selim Cinek67b22602014-03-10 15:40:16 +0100177
Daniel Sandler6a858c32012-03-12 14:38:58 -0400178import java.io.FileDescriptor;
179import java.io.PrintWriter;
180import java.util.ArrayList;
Christoph Studer92b389d2014-04-01 18:44:40 +0200181import java.util.Collection;
182import java.util.Collections;
Selim Cinekb5605e52015-02-20 18:21:41 +0100183import java.util.HashMap;
Dan Sandler16128f42014-05-21 12:48:22 -0400184import java.util.List;
John Spurlock7bbb9f62014-10-21 12:15:28 -0400185import java.util.Map;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700186
187import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
188import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
189import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
190import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
191import static android.app.StatusBarManager.windowStateToString;
192import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
193import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
194import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
195import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
196import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
197import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
198import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
Daniel Sandler6a858c32012-03-12 14:38:58 -0400199
Jorim Jaggiecbab362014-04-23 16:13:15 +0200200public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Selim Cinek8d490d42015-04-10 00:05:50 -0700201 DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
202 HeadsUpManager.OnHeadsUpChangedListener {
Joe Onoratofd52b182010-11-10 18:00:52 -0800203 static final String TAG = "PhoneStatusBar";
Daniel Sandler198a0302012-08-17 16:04:31 -0400204 public static final boolean DEBUG = BaseStatusBar.DEBUG;
Chris Wren6d15a362013-08-20 18:46:29 -0400205 public static final boolean SPEW = false;
Daniel Sandler7579bca2011-08-18 15:47:26 -0400206 public static final boolean DUMPTRUCK = true; // extra dumpsys info
Daniel Sandlerfa027f52013-04-11 22:01:47 -0400207 public static final boolean DEBUG_GESTURES = false;
Dan Sandler16128f42014-05-21 12:48:22 -0400208 public static final boolean DEBUG_MEDIA = false;
209 public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
Joe Onorato808182d2010-07-09 18:52:06 -0400210
John Spurlock342cad72013-10-08 09:36:50 -0400211 public static final boolean DEBUG_WINDOW_STATE = false;
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400212
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400213 // additional instrumentation for testing purposes; intended to be left on during development
Daniel Sandler7c351742011-10-17 10:48:06 -0400214 public static final boolean CHATTY = DEBUG;
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400215
Dan Sandler16128f42014-05-21 12:48:22 -0400216 public static final boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
217
Adrian Roos8e3e8362015-07-16 19:42:22 -0700218 public static final String ACTION_FAKE_ARTWORK = "fake_artwork";
219
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400220 private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
Daniel Sandler11cf1782012-09-27 14:03:08 -0400221 private static final int MSG_CLOSE_PANELS = 1001;
222 private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
Jorim Jaggi826730a2014-12-08 21:05:13 +0100223 private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
Winson Chungb1f74992014-08-08 12:53:09 -0700224 // 1020-1040 reserved for BaseStatusBar
Joe Onorato808182d2010-07-09 18:52:06 -0400225
Jorim Jaggi826730a2014-12-08 21:05:13 +0100226 // Time after we abort the launch transition.
227 private static final long LAUNCH_TRANSITION_TIMEOUT_MS = 5000;
228
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400229 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
230
John Spurlocke1f366f2013-08-05 12:22:40 -0400231 private static final int STATUS_OR_NAV_TRANSIENT =
232 View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
John Spurlock32beb2c2013-03-11 10:16:47 -0400233 private static final long AUTOHIDE_TIMEOUT_MS = 3000;
John Spurlocke1f366f2013-08-05 12:22:40 -0400234
Christoph Studer92b389d2014-04-01 18:44:40 +0200235 /** The minimum delay in ms between reports of notification visibility. */
236 private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
237
Jorim Jaggi93a2bb22014-06-02 19:57:28 +0200238 /**
239 * The delay to reset the hint text when the hint animation is finished running.
240 */
241 private static final int HINT_RESET_DELAY_MS = 1200;
242
John Spurlock7b414672014-07-18 13:02:39 -0400243 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
244 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
245 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
246 .build();
247
Selim Cinekbaa23272014-07-08 18:01:07 +0200248 public static final int FADE_KEYGUARD_START_DELAY = 100;
249 public static final int FADE_KEYGUARD_DURATION = 300;
Jorim Jaggi90978852015-08-18 19:55:53 -0700250 public static final int FADE_KEYGUARD_DURATION_PULSING = 96;
Selim Cinekbaa23272014-07-08 18:01:07 +0200251
Jason Monk815e0572014-08-12 17:26:36 -0400252 /** Allow some time inbetween the long press for back and recents. */
253 private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
254
Adrian Roos2f2bd9a2015-06-04 18:11:14 -0700255 /** If true, the system is in the half-boot-to-decryption-screen state.
256 * Prudently disable QS and notifications. */
Adrian Roos21d2a252015-06-01 13:59:59 -0700257 private static final boolean ONLY_CORE_APPS;
258
Adrian Roos52738322016-01-29 08:49:21 -0800259 /** If true, the lockscreen will show a distinct wallpaper */
Adrian Roose381c162016-02-11 15:26:42 -0800260 private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
Adrian Roos52738322016-01-29 08:49:21 -0800261
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700262 /* If true, the device supports freeform window management.
263 * This affects the status bar UI. */
264 private static final boolean FREEFORM_WINDOW_MANAGEMENT;
265
Adrian Roos21d2a252015-06-01 13:59:59 -0700266 static {
267 boolean onlyCoreApps;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700268 boolean freeformWindowManagement;
Adrian Roos21d2a252015-06-01 13:59:59 -0700269 try {
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700270 IPackageManager packageManager =
271 IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
272 onlyCoreApps = packageManager.isOnlyCoreApps();
273 freeformWindowManagement = packageManager.hasSystemFeature(
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700274 PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT, 0);
Adrian Roos21d2a252015-06-01 13:59:59 -0700275 } catch (RemoteException e) {
276 onlyCoreApps = false;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700277 freeformWindowManagement = false;
Adrian Roos21d2a252015-06-01 13:59:59 -0700278 }
279 ONLY_CORE_APPS = onlyCoreApps;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700280 FREEFORM_WINDOW_MANAGEMENT = freeformWindowManagement;
Adrian Roos21d2a252015-06-01 13:59:59 -0700281 }
282
Joe Onoratofd52b182010-11-10 18:00:52 -0800283 PhoneStatusBarPolicy mIconPolicy;
Joe Onorato808182d2010-07-09 18:52:06 -0400284
Daniel Sandler2b697352011-07-22 16:23:09 -0400285 // These are no longer handled by the policy, because we need custom strategies for them
John Spurlockaf8d6c42014-05-07 17:49:08 -0400286 BluetoothControllerImpl mBluetoothController;
Jason Monk3d5f5512014-07-25 11:17:28 -0400287 SecurityControllerImpl mSecurityController;
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -0800288 protected BatteryController mBatteryController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400289 LocationControllerImpl mLocationController;
290 NetworkControllerImpl mNetworkController;
Jason Monk51e4dc02014-07-22 12:00:47 -0400291 HotspotControllerImpl mHotspotController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400292 RotationLockControllerImpl mRotationLockController;
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200293 UserInfoController mUserInfoController;
Muyuan Li40e11352016-03-23 11:43:58 -0700294 protected ZenModeController mZenModeController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400295 CastControllerImpl mCastController;
John Spurlock86005342014-05-23 11:58:00 -0400296 VolumeComponent mVolumeComponent;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700297 KeyguardUserSwitcher mKeyguardUserSwitcher;
Adrian Roosb83777b2014-06-30 15:11:53 +0200298 FlashlightController mFlashlightController;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800299 protected UserSwitcherController mUserSwitcherController;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200300 NextAlarmController mNextAlarmController;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800301 protected KeyguardMonitor mKeyguardMonitor;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200302 BrightnessMirrorController mBrightnessMirrorController;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200303 AccessibilityController mAccessibilityController;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700304 FingerprintUnlockController mFingerprintUnlockController;
Jorim Jaggi86905582016-02-09 21:36:09 -0800305 LightStatusBarController mLightStatusBarController;
Vadim Tryshev12a30e82016-02-12 15:39:28 -0800306 protected LockscreenWallpaper mLockscreenWallpaper;
Jim Miller5e6af442011-12-02 18:24:26 -0800307
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400308 int mNaturalBarHeight = -1;
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100309
Joe Onorato808182d2010-07-09 18:52:06 -0400310 Display mDisplay;
Daniel Sandlere680f542012-09-28 12:22:27 -0400311 Point mCurrentDisplaySize = new Point();
Joe Onorato808182d2010-07-09 18:52:06 -0400312
Xiaohui Chend839d1a2016-01-21 13:05:02 -0800313 protected StatusBarWindowView mStatusBarWindow;
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700314 protected PhoneStatusBarView mStatusBarView;
John Spurlockd4e65752013-08-28 14:17:09 -0400315 private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800316 protected StatusBarWindowManager mStatusBarWindowManager;
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200317 private UnlockMethodCache mUnlockMethodCache;
John Spurlockbf370992014-06-17 13:58:31 -0400318 private DozeServiceHost mDozeServiceHost;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -0700319 private boolean mWakeUpComingFromTouch;
320 private PointF mWakeUpTouchLocation;
Selim Cinek1b6f8192015-09-03 16:01:53 -0700321 private boolean mScreenTurningOn;
Daniel Sandlera310af82012-04-24 01:20:13 -0400322
Joe Onorato808182d2010-07-09 18:52:06 -0400323 int mPixelFormat;
Joe Onorato808182d2010-07-09 18:52:06 -0400324 Object mQueueLock = new Object();
325
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700326 protected StatusBarIconController mIconController;
Joe Onorato808182d2010-07-09 18:52:06 -0400327
328 // expanded notifications
Xiaohui Chenea4b6ba2016-02-18 10:53:17 -0800329 protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
Joe Onorato808182d2010-07-09 18:52:06 -0400330 View mExpandedContents;
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400331 TextView mNotificationPanelDebugText;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400332
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400333 // settings
John Spurlockaf8d6c42014-05-07 17:49:08 -0400334 private QSPanel mQSPanel;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400335
Joe Onorato808182d2010-07-09 18:52:06 -0400336 // top bar
Jason Monk0e1101d2015-10-07 13:06:09 -0400337 BaseStatusBarHeader mHeader;
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700338 protected KeyguardStatusBarView mKeyguardStatusBar;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200339 View mKeyguardStatusView;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200340 KeyguardBottomAreaView mKeyguardBottomArea;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200341 boolean mLeaveOpenOnKeyguardHide;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200342 KeyguardIndicationController mKeyguardIndicationController;
Jorim Jaggie70d31f2014-04-24 22:08:30 +0200343
Adrian Roos46df1ca2015-09-11 12:38:43 -0700344 // Keyguard is going away soon.
345 private boolean mKeyguardGoingAway;
346 // Keyguard is actually fading away now.
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700347 private boolean mKeyguardFadingAway;
348 private long mKeyguardFadingAwayDelay;
349 private long mKeyguardFadingAwayDuration;
350
Adrian Roos3aec6382016-02-05 14:19:01 -0800351 // RemoteInputView to be activated after unlock
352 private View mPendingRemoteInputView;
Ricky Waicd35def2016-05-03 11:07:07 +0100353 private View mPendingWorkRemoteInputView;
Adrian Roos3aec6382016-02-05 14:19:01 -0800354
Selim Cinek5f71bee2015-11-18 10:25:23 -0800355 int mMaxAllowedKeyguardNotifications;
Daniel Sandlerd3090562011-08-09 00:28:44 -0400356
Joe Onorato808182d2010-07-09 18:52:06 -0400357 boolean mExpandedVisible;
358
John Spurlockd4e65752013-08-28 14:17:09 -0400359 private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400360
Joe Onorato808182d2010-07-09 18:52:06 -0400361 // the tracker view
Joe Onorato808182d2010-07-09 18:52:06 -0400362 int mTrackingPosition; // the position of the top of the tracking view.
Joe Onorato808182d2010-07-09 18:52:06 -0400363
Joe Onorato808182d2010-07-09 18:52:06 -0400364 // Tracking finger for opening/closing.
Joe Onorato808182d2010-07-09 18:52:06 -0400365 boolean mTracking;
Joe Onorato808182d2010-07-09 18:52:06 -0400366
Joe Onorato808182d2010-07-09 18:52:06 -0400367 int[] mAbsPos = new int[2];
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200368 ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
Chet Haase2f2022a2011-10-11 06:41:59 -0700369
Joe Onorato808182d2010-07-09 18:52:06 -0400370 // for disabling the status bar
Benjamin Franzcde0a2a2015-04-23 17:19:48 +0100371 int mDisabled1 = 0;
372 int mDisabled2 = 0;
Joe Onorato808182d2010-07-09 18:52:06 -0400373
Daniel Sandler60ee2562011-07-22 12:34:33 -0400374 // tracking calls to View.setSystemUiVisibility()
375 int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
Jorim Jaggi86905582016-02-09 21:36:09 -0800376 private final Rect mLastFullscreenStackBounds = new Rect();
377 private final Rect mLastDockedStackBounds = new Rect();
Daniel Sandler60ee2562011-07-22 12:34:33 -0400378
Adrian Roos389beec2015-05-12 13:33:25 -0700379 // last value sent to window manager
380 private int mLastDispatchedSystemUiVisibility = ~View.SYSTEM_UI_FLAG_VISIBLE;
381
Daniel Sandler36412a72011-08-04 09:35:13 -0400382 DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700383
Daniel Sandler33805342012-07-23 15:45:12 -0400384 // XXX: gesture research
Daniel Sandler151f00d2012-10-02 22:33:08 -0400385 private final GestureRecorder mGestureRec = DEBUG_GESTURES
John Spurlock209bede2013-07-17 12:23:27 -0400386 ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
Daniel Sandler151f00d2012-10-02 22:33:08 -0400387 : null;
Daniel Sandler33805342012-07-23 15:45:12 -0400388
Jason Monk18f99d92014-09-11 13:36:42 -0400389 private ScreenPinningRequest mScreenPinningRequest;
390
Daniel Sandler328310c2011-09-23 15:56:52 -0400391 private int mNavigationIconHints = 0;
Jason Monk4ae97d32014-12-17 10:14:33 -0500392 private HandlerThread mHandlerThread;
Daniel Sandler328310c2011-09-23 15:56:52 -0400393
John Spurlock919adac2012-10-02 16:41:12 -0400394 // ensure quick settings is disabled until the current user makes it through the setup wizard
395 private boolean mUserSetup = false;
396 private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
397 @Override
398 public void onChange(boolean selfChange) {
399 final boolean userSetup = 0 != Settings.Secure.getIntForUser(
400 mContext.getContentResolver(),
401 Settings.Secure.USER_SETUP_COMPLETE,
402 0 /*default */,
403 mCurrentUserId);
John Spurlockcd686b52013-06-05 10:13:46 -0400404 if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
John Spurlocke4e8c562012-10-04 09:55:01 -0400405 "selfChange=%s userSetup=%s mUserSetup=%s",
406 selfChange, userSetup, mUserSetup));
John Spurlock73203eb2014-04-15 16:14:46 -0400407
John Spurlock919adac2012-10-02 16:41:12 -0400408 if (userSetup != mUserSetup) {
409 mUserSetup = userSetup;
John Spurlock919adac2012-10-02 16:41:12 -0400410 if (!mUserSetup && mStatusBarView != null)
411 animateCollapseQuickSettings();
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700412 if (mKeyguardBottomArea != null) {
413 mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
414 }
Jason Monkfd57ea72016-04-29 13:37:58 -0400415 if (mNetworkController != null) {
416 mNetworkController.setUserSetupComplete(mUserSetup);
417 }
John Spurlock919adac2012-10-02 16:41:12 -0400418 }
John Spurlock604a5ee2015-06-01 12:27:22 -0400419 if (mIconPolicy != null) {
420 mIconPolicy.setCurrentUserSetup(mUserSetup);
421 }
John Spurlock919adac2012-10-02 16:41:12 -0400422 }
423 };
424
Chris Wrenf6e83f42013-09-11 14:02:59 -0400425 final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
426 @Override
427 public void onChange(boolean selfChange) {
428 boolean wasUsing = mUseHeadsUp;
Jason Monkf7019542014-07-31 12:42:25 -0400429 mUseHeadsUp = ENABLE_HEADS_UP && !mDisableNotificationAlerts
430 && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
Chris Wren10d82df2014-03-01 10:34:51 -0500431 mContext.getContentResolver(), Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Chris Wren7bd241232014-02-28 16:25:05 -0500432 Settings.Global.HEADS_UP_OFF);
Chris Wren22ae46e2014-02-26 18:08:09 -0500433 mHeadsUpTicker = mUseHeadsUp && 0 != Settings.Global.getInt(
434 mContext.getContentResolver(), SETTING_HEADS_UP_TICKER, 0);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400435 Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
436 if (wasUsing != mUseHeadsUp) {
437 if (!mUseHeadsUp) {
438 Log.d(TAG, "dismissing any existing heads up notification on disable event");
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700439 mHeadsUpManager.releaseAllImmediately();
Chris Wrenf6e83f42013-09-11 14:02:59 -0400440 }
441 }
442 }
443 };
444
John Spurlockcfc359a2013-09-05 10:42:03 -0400445 private int mInteractingWindows;
John Spurlock32beb2c2013-03-11 10:16:47 -0400446 private boolean mAutohideSuspended;
John Spurlockd4e65752013-08-28 14:17:09 -0400447 private int mStatusBarMode;
448 private int mNavigationBarMode;
Selim Cinek5f71bee2015-11-18 10:25:23 -0800449 private int mMaxKeyguardNotifications;
Jorim Jaggid41083a2014-09-12 02:54:40 +0200450
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200451 private ViewMediatorCallback mKeyguardViewMediatorCallback;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800452 protected ScrimController mScrimController;
453 protected DozeScrimController mDozeScrimController;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200454
John Spurlock32beb2c2013-03-11 10:16:47 -0400455 private final Runnable mAutohide = new Runnable() {
456 @Override
457 public void run() {
John Spurlocke1f366f2013-08-05 12:22:40 -0400458 int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT;
John Spurlock9deaa282013-07-25 13:03:47 -0400459 if (mSystemUiVisibility != requested) {
460 notifyUiVisibilityChanged(requested);
461 }
John Spurlock32beb2c2013-03-11 10:16:47 -0400462 }};
463
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700464 private boolean mWaitingForKeyguardExit;
John Spurlockbf370992014-06-17 13:58:31 -0400465 private boolean mDozing;
Jorim Jaggi83969702015-06-05 14:59:24 -0700466 private boolean mDozingRequested;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800467 protected boolean mScrimSrcModeEnabled;
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100468
Selim Cinekc18010f2016-01-20 13:41:30 -0800469 public static final Interpolator ALPHA_IN = Interpolators.ALPHA_IN;
470 public static final Interpolator ALPHA_OUT = Interpolators.ALPHA_OUT;
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200471
Selim Cineka0fad3b2014-09-19 17:20:05 +0200472 private BackDropView mBackdrop;
Dan Sandler16128f42014-05-21 12:48:22 -0400473 private ImageView mBackdropFront, mBackdropBack;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200474 private PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
475 private PorterDuffXfermode mSrcOverXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);
Dan Sandler16128f42014-05-21 12:48:22 -0400476
477 private MediaSessionManager mMediaSessionManager;
478 private MediaController mMediaController;
479 private String mMediaNotificationKey;
480 private MediaMetadata mMediaMetadata;
481 private MediaController.Callback mMediaListener
482 = new MediaController.Callback() {
483 @Override
484 public void onPlaybackStateChanged(PlaybackState state) {
485 super.onPlaybackStateChanged(state);
486 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onPlaybackStateChanged: " + state);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -0400487 if (state != null) {
488 if (!isPlaybackActive(state.getState())) {
489 clearCurrentMediaNotification();
Adrian Roos52738322016-01-29 08:49:21 -0800490 updateMediaMetaData(true, true);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -0400491 }
492 }
Dan Sandler16128f42014-05-21 12:48:22 -0400493 }
494
495 @Override
496 public void onMetadataChanged(MediaMetadata metadata) {
497 super.onMetadataChanged(metadata);
498 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onMetadataChanged: " + metadata);
499 mMediaMetadata = metadata;
Adrian Roos52738322016-01-29 08:49:21 -0800500 updateMediaMetaData(true, true);
Dan Sandler16128f42014-05-21 12:48:22 -0400501 }
502 };
503
504 private final OnChildLocationsChangedListener mOnChildLocationsChangedListener =
505 new OnChildLocationsChangedListener() {
506 @Override
507 public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout) {
508 userActivity();
509 }
510 };
511
Benjamin Franzcde0a2a2015-04-23 17:19:48 +0100512 private int mDisabledUnmodified1;
513 private int mDisabledUnmodified2;
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200514
Christoph Studer92b389d2014-04-01 18:44:40 +0200515 /** Keys of notifications currently visible to the user. */
Chris Wrend1dbc922015-06-19 17:51:16 -0400516 private final ArraySet<NotificationVisibility> mCurrentlyVisibleNotifications =
517 new ArraySet<>();
Christoph Studer92b389d2014-04-01 18:44:40 +0200518 private long mLastVisibilityReportUptimeMs;
519
John Spurlockbf370992014-06-17 13:58:31 -0400520 private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
521
Selim Cinekbaa23272014-07-08 18:01:07 +0200522 private Runnable mLaunchTransitionEndRunnable;
523 private boolean mLaunchTransitionFadingAway;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +0200524 private ExpandableNotificationRow mDraggedDownRow;
Selim Cinek372d1bd2015-08-14 13:19:37 -0700525 private boolean mLaunchCameraOnScreenTurningOn;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -0700526 private boolean mLaunchCameraOnFinishedGoingToSleep;
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700527 private int mLastCameraLaunchSource;
Selim Cinek372d1bd2015-08-14 13:19:37 -0700528 private PowerManager.WakeLock mGestureWakeLock;
Selim Cinek69ff8af2015-08-25 19:03:48 -0700529 private Vibrator mVibrator;
Jorim Jaggi362dd6d2014-07-09 19:04:07 +0200530
Christoph Studer2231c6e2014-12-19 12:40:13 +0100531 // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
532 private int mLastLoggedStateFingerprint;
533
Jorim Jaggi18f18ae2015-09-10 15:48:21 -0700534 /**
535 * If set, the device has started going to sleep but isn't fully non-interactive yet.
536 */
537 protected boolean mStartedGoingToSleep;
538
Selim Cinek3776fe02016-02-04 13:32:43 -0800539 private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_HUN
Chris Wren35a7c922015-06-22 16:31:01 -0400540 | StackViewState.LOCATION_MAIN_AREA;
Christoph Studer92b389d2014-04-01 18:44:40 +0200541
542 private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
543 new OnChildLocationsChangedListener() {
544 @Override
545 public void onChildLocationsChanged(
546 NotificationStackScrollLayout stackScrollLayout) {
547 if (mHandler.hasCallbacks(mVisibilityReporter)) {
548 // Visibilities will be reported when the existing
549 // callback is executed.
550 return;
551 }
552 // Calculate when we're allowed to run the visibility
553 // reporter. Note that this timestamp might already have
554 // passed. That's OK, the callback will just be executed
555 // ASAP.
556 long nextReportUptimeMs =
557 mLastVisibilityReportUptimeMs + VISIBILITY_REPORT_MIN_DELAY_MS;
558 mHandler.postAtTime(mVisibilityReporter, nextReportUptimeMs);
559 }
560 };
561
562 // Tracks notifications currently visible in mNotificationStackScroller and
563 // emits visibility events via NoMan on changes.
564 private final Runnable mVisibilityReporter = new Runnable() {
Chris Wrend1dbc922015-06-19 17:51:16 -0400565 private final ArraySet<NotificationVisibility> mTmpNewlyVisibleNotifications =
566 new ArraySet<>();
567 private final ArraySet<NotificationVisibility> mTmpCurrentlyVisibleNotifications =
568 new ArraySet<>();
569 private final ArraySet<NotificationVisibility> mTmpNoLongerVisibleNotifications =
570 new ArraySet<>();
Christoph Studer92b389d2014-04-01 18:44:40 +0200571
572 @Override
573 public void run() {
574 mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
Chris Wrend1dbc922015-06-19 17:51:16 -0400575 final String mediaKey = getCurrentMediaNotificationKey();
Christoph Studer92b389d2014-04-01 18:44:40 +0200576
577 // 1. Loop over mNotificationData entries:
578 // A. Keep list of visible notifications.
579 // B. Keep list of previously hidden, now visible notifications.
580 // 2. Compute no-longer visible notifications by removing currently
581 // visible notifications from the set of previously visible
582 // notifications.
583 // 3. Report newly visible and no-longer visible notifications.
584 // 4. Keep currently visible notifications for next report.
Christoph Studerc8db24b2014-07-25 17:50:30 +0200585 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
586 int N = activeNotifications.size();
Christoph Studer92b389d2014-04-01 18:44:40 +0200587 for (int i = 0; i < N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +0200588 Entry entry = activeNotifications.get(i);
Christoph Studer92b389d2014-04-01 18:44:40 +0200589 String key = entry.notification.getKey();
Chris Wrend1dbc922015-06-19 17:51:16 -0400590 boolean isVisible =
Christoph Studer92b389d2014-04-01 18:44:40 +0200591 (mStackScroller.getChildLocation(entry.row) & VISIBLE_LOCATIONS) != 0;
Chris Wrend1dbc922015-06-19 17:51:16 -0400592 NotificationVisibility visObj = NotificationVisibility.obtain(key, i, isVisible);
593 boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(visObj);
594 if (isVisible) {
Christoph Studer92b389d2014-04-01 18:44:40 +0200595 // Build new set of visible notifications.
Chris Wrend1dbc922015-06-19 17:51:16 -0400596 mTmpCurrentlyVisibleNotifications.add(visObj);
597 if (!previouslyVisible) {
598 mTmpNewlyVisibleNotifications.add(visObj);
599 }
600 } else {
601 // release object
602 visObj.recycle();
Christoph Studer92b389d2014-04-01 18:44:40 +0200603 }
604 }
Chris Wrend1dbc922015-06-19 17:51:16 -0400605 mTmpNoLongerVisibleNotifications.addAll(mCurrentlyVisibleNotifications);
606 mTmpNoLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200607
608 logNotificationVisibilityChanges(
Chris Wrend1dbc922015-06-19 17:51:16 -0400609 mTmpNewlyVisibleNotifications, mTmpNoLongerVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200610
Chris Wrend1dbc922015-06-19 17:51:16 -0400611 recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200612 mCurrentlyVisibleNotifications.addAll(mTmpCurrentlyVisibleNotifications);
613
Chris Wrend1dbc922015-06-19 17:51:16 -0400614 recycleAllVisibilityObjects(mTmpNoLongerVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200615 mTmpCurrentlyVisibleNotifications.clear();
Chris Wrend1dbc922015-06-19 17:51:16 -0400616 mTmpNewlyVisibleNotifications.clear();
617 mTmpNoLongerVisibleNotifications.clear();
Christoph Studer92b389d2014-04-01 18:44:40 +0200618 }
619 };
620
Chris Wrend1dbc922015-06-19 17:51:16 -0400621 private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
622 final int N = array.size();
623 for (int i = 0 ; i < N; i++) {
624 array.valueAt(i).recycle();
625 }
626 array.clear();
627 }
628
Jorim Jaggiecbab362014-04-23 16:13:15 +0200629 private final View.OnClickListener mOverflowClickListener = new View.OnClickListener() {
630 @Override
631 public void onClick(View v) {
632 goToLockedShade(null);
633 }
634 };
Selim Cinekb5605e52015-02-20 18:21:41 +0100635 private HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>> mTmpChildOrderMap
636 = new HashMap<>();
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700637 private RankingMap mLatestRankingMap;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700638 private boolean mNoAnimationOnNextBarModeChange;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700639 private FalsingManager mFalsingManager;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200640
Joe Onorato808182d2010-07-09 18:52:06 -0400641 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400642 public void start() {
643 mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
644 .getDefaultDisplay();
Daniel Sandler7e8ae502013-10-10 23:38:19 -0400645 updateDisplaySize();
Jorim Jaggi0e664392014-09-27 01:30:22 +0200646 mScrimSrcModeEnabled = mContext.getResources().getBoolean(
647 R.bool.config_status_bar_scrim_behind_use_src);
Adrian Roos75fa3852015-01-27 20:21:44 +0100648
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500649 super.start(); // calls createAndAddWindows()
Joe Onorato808182d2010-07-09 18:52:06 -0400650
Dan Sandler16128f42014-05-21 12:48:22 -0400651 mMediaSessionManager
652 = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
653 // TODO: use MediaSessionManager.SessionListener to hook us up to future updates
654 // in session state
655
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400656 addNavigationBar();
657
Joe Onorato808182d2010-07-09 18:52:06 -0400658 // Lastly, call to the icon policy to install/update all the icons.
Jason Monk07473ce2016-01-05 14:59:19 -0500659 mIconPolicy = new PhoneStatusBarPolicy(mContext, mIconController, mCastController,
Jason Monk3e189872016-01-12 09:10:34 -0500660 mHotspotController, mUserInfoController, mBluetoothController,
Jason Monkf23aa992016-01-22 16:45:21 -0500661 mRotationLockController, mNetworkController.getDataSaverController());
John Spurlock604a5ee2015-06-01 12:27:22 -0400662 mIconPolicy.setCurrentUserSetup(mUserSetup);
John Spurlocke677d712014-02-13 12:52:19 -0500663 mSettingsObserver.onChange(false); // set up
Chris Wrenf6e83f42013-09-11 14:02:59 -0400664
665 mHeadsUpObserver.onChange(true); // set up
666 if (ENABLE_HEADS_UP) {
667 mContext.getContentResolver().registerContentObserver(
Chris Wren10d82df2014-03-01 10:34:51 -0500668 Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED), true,
Chris Wrenf6e83f42013-09-11 14:02:59 -0400669 mHeadsUpObserver);
Chris Wren22ae46e2014-02-26 18:08:09 -0500670 mContext.getContentResolver().registerContentObserver(
671 Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
672 mHeadsUpObserver);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400673 }
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200674 mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
Christoph Studer2231c6e2014-12-19 12:40:13 +0100675 mUnlockMethodCache.addListener(this);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100676 startKeyguard();
John Spurlockbf370992014-06-17 13:58:31 -0400677
678 mDozeServiceHost = new DozeServiceHost();
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700679 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mDozeServiceHost);
Jeff Brown4d69e222014-09-18 15:27:50 -0700680 putComponent(DozeHost.class, mDozeServiceHost);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200681 putComponent(PhoneStatusBar.class, this);
John Spurlock89f060a2014-07-16 21:03:15 -0400682
683 setControllerUsers();
Chris Wrencd8f4f72014-08-27 18:48:13 -0400684
685 notifyUserAboutHiddenNotifications();
Jason Monk18f99d92014-09-11 13:36:42 -0400686
687 mScreenPinningRequest = new ScreenPinningRequest(mContext);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700688 mFalsingManager = FalsingManager.getInstance(mContext);
Joe Onorato808182d2010-07-09 18:52:06 -0400689 }
690
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700691 protected void createIconController() {
692 mIconController = new StatusBarIconController(
693 mContext, mStatusBarView, mKeyguardStatusBar, this);
694 }
695
Joe Onorato808182d2010-07-09 18:52:06 -0400696 // ================================================================================
697 // Constructing the view
698 // ================================================================================
Jim Millere898ac52012-04-06 17:10:57 -0700699 protected PhoneStatusBarView makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400700 final Context context = mContext;
Joe Onorato808182d2010-07-09 18:52:06 -0400701
Daniel Sandler6e8db882011-10-26 15:40:51 -0400702 updateDisplaySize(); // populates mDisplayMetrics
Jorim Jaggi2e115c52014-07-01 21:27:58 +0200703 updateResources();
Joe Onorato808182d2010-07-09 18:52:06 -0400704
Xiaohui Chend839d1a2016-01-21 13:05:02 -0800705 inflateStatusBarWindow(context);
Selim Cinek4e6b2d32015-06-25 20:15:33 -0400706 mStatusBarWindow.setService(this);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400707 mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
708 @Override
709 public boolean onTouch(View v, MotionEvent event) {
John Spurlock9deaa282013-07-25 13:03:47 -0400710 checkUserAutohide(v, event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400711 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandler37a38aa2013-02-13 17:15:57 -0500712 if (mExpandedVisible) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400713 animateCollapsePanels();
Daniel Sandler21b274e2012-05-02 15:07:51 -0400714 }
715 }
Chris Wren5de6e942012-05-16 14:22:21 -0400716 return mStatusBarWindow.onTouchEvent(event);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700717 }
718 });
Daniel Sandler21b274e2012-05-02 15:07:51 -0400719
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100720 mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
721 R.id.notification_panel);
Daniel Sandler040c2e42012-10-17 00:56:33 -0400722 mNotificationPanel.setStatusBar(this);
Selim Cinek53f8e7d2016-03-25 02:28:01 -0700723 mNotificationPanel.setGroupManager(mGroupManager);
Joe Onorato808182d2010-07-09 18:52:06 -0400724
Xiaohui Chen9f967112016-01-07 14:14:06 -0800725 mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
726 mStatusBarView.setBar(this);
727 mStatusBarView.setPanel(mNotificationPanel);
728
Jeff Brown98365d72012-08-19 20:30:52 -0700729 if (!ActivityManager.isHighEndGfx()) {
Romain Guy328b3582012-05-08 15:30:57 -0700730 mStatusBarWindow.setBackground(null);
Alan Viverette4a357cd2015-03-18 18:37:18 -0700731 mNotificationPanel.setBackground(new FastColorDrawable(context.getColor(
Romain Guy648342f2012-05-25 10:44:45 -0700732 R.color.notification_panel_solid_background)));
Romain Guy328b3582012-05-08 15:30:57 -0700733 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700734
Selim Cinek83bc7832015-10-22 13:26:54 -0700735 mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow, mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700736 mHeadsUpManager.setBar(this);
737 mHeadsUpManager.addListener(this);
738 mHeadsUpManager.addListener(mNotificationPanel);
Selim Cinekef5127e2015-12-21 16:55:58 -0800739 mHeadsUpManager.addListener(mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700740 mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
Selim Cinekfbe9a442015-04-13 16:09:49 -0700741 mNotificationData.setHeadsUpManager(mHeadsUpManager);
Selim Cinek967ed2a2016-04-08 18:29:11 -0700742 mGroupManager.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700743
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400744 if (MULTIUSER_DEBUG) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100745 mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
746 R.id.header_debug_info);
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400747 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
748 }
Joe Onorato808182d2010-07-09 18:52:06 -0400749
Daniel Sandler0129b312011-05-11 11:54:11 -0400750 try {
Jeff Brown98365d72012-08-19 20:30:52 -0700751 boolean showNav = mWindowManagerService.hasNavigationBar();
John Spurlockcd686b52013-06-05 10:13:46 -0400752 if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
Daniel Sandler0129b312011-05-11 11:54:11 -0400753 if (showNav) {
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800754 createNavigationBarView(context);
Daniel Sandler0129b312011-05-11 11:54:11 -0400755 }
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400756 } catch (RemoteException ex) {
757 // no window manager? good luck with that
Daniel Sandler0129b312011-05-11 11:54:11 -0400758 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400759
Selim Cineke70d6532015-04-24 16:46:13 -0700760 mAssistManager = new AssistManager(this, context);
761
Joe Onorato808182d2010-07-09 18:52:06 -0400762 // figure out which pixel-format to use for the status bar.
Daniel Sandlerf733c2a2011-09-25 15:03:40 -0400763 mPixelFormat = PixelFormat.OPAQUE;
Daniel Sandler173bae22012-09-25 14:37:42 -0400764
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100765 mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
766 R.id.notification_stack_scroller);
767 mStackScroller.setLongPressListener(getNotificationLongClicker());
Selim Cinek19c8c702014-08-25 22:09:19 +0200768 mStackScroller.setPhoneStatusBar(this);
Selim Cinekb5605e52015-02-20 18:21:41 +0100769 mStackScroller.setGroupManager(mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700770 mStackScroller.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb5605e52015-02-20 18:21:41 +0100771 mGroupManager.setOnGroupChangeListener(mStackScroller);
Selim Cinek80a14e52014-03-27 16:58:04 +0100772
Selim Cinek3e7592d2016-04-11 09:35:54 +0800773 inflateOverflowContainer();
Selim Cinek01af3342016-02-09 19:25:31 -0800774 inflateEmptyShadeView();
775 inflateDismissView();
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100776 mExpandedContents = mStackScroller;
Selim Cinek67b22602014-03-10 15:40:16 +0100777
Selim Cineka0fad3b2014-09-19 17:20:05 +0200778 mBackdrop = (BackDropView) mStatusBarWindow.findViewById(R.id.backdrop);
779 mBackdropFront = (ImageView) mBackdrop.findViewById(R.id.backdrop_front);
780 mBackdropBack = (ImageView) mBackdrop.findViewById(R.id.backdrop_back);
781
782 ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
783 ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
Selim Cinekaac93252015-04-14 20:04:12 -0700784 View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
Xiaohui Chen5da71352016-02-22 10:04:41 -0800785 mScrimController = SystemUIFactory.getInstance().createScrimController(
Selim Cinek25503252016-03-03 15:31:43 -0800786 scrimBehind, scrimInFront, headsUpScrim);
787 if (mScrimSrcModeEnabled) {
788 Runnable runnable = new Runnable() {
789 @Override
790 public void run() {
791 boolean asSrc = mBackdrop.getVisibility() != View.VISIBLE;
792 mScrimController.setDrawBehindAsSrc(asSrc);
793 mStackScroller.setDrawBackgroundAsSrc(asSrc);
794 }
795 };
796 mBackdrop.setOnVisibilityChangedRunnable(runnable);
797 runnable.run();
798 }
Selim Cinekaac93252015-04-14 20:04:12 -0700799 mHeadsUpManager.addListener(mScrimController);
800 mStackScroller.setScrimController(mScrimController);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200801 mStatusBarView.setScrimController(mScrimController);
Jorim Jaggi048af1f2014-11-11 22:51:10 +0100802 mDozeScrimController = new DozeScrimController(mScrimController, context);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200803
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200804 mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200805 mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200806 mKeyguardBottomArea =
807 (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
808 mKeyguardBottomArea.setActivityStarter(this);
Selim Cineke70d6532015-04-24 16:46:13 -0700809 mKeyguardBottomArea.setAssistManager(mAssistManager);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200810 mKeyguardIndicationController = new KeyguardIndicationController(mContext,
811 (KeyguardIndicationTextView) mStatusBarWindow.findViewById(
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700812 R.id.keyguard_indication_text),
813 mKeyguardBottomArea.getLockIcon());
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200814 mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400815
Adrian Roose381c162016-02-11 15:26:42 -0800816 if (ENABLE_LOCKSCREEN_WALLPAPER) {
817 mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
818 }
819
Xiaohui Chenf43491f2016-02-01 12:19:35 -0800820 // set the initial view visibility
Joe Onorato808182d2010-07-09 18:52:06 -0400821 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400822
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700823 createIconController();
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100824
Jason Monk4ae97d32014-12-17 10:14:33 -0500825 // Background thread for any controllers that need it.
826 mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
827 mHandlerThread.start();
828
Daniel Sandler2b697352011-07-22 16:23:09 -0400829 // Other icons
Jason Monk05b86bc2015-05-19 14:21:28 -0400830 mLocationController = new LocationControllerImpl(mContext,
831 mHandlerThread.getLooper()); // will post a notification
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700832 mBatteryController = createBatteryController();
John Spurlock0ff62e02014-07-22 16:15:08 -0400833 mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
834 @Override
Jason Monkc06fbb12016-01-08 14:12:18 -0500835 public void onPowerSaveChanged(boolean isPowerSave) {
John Spurlock0ff62e02014-07-22 16:15:08 -0400836 mHandler.post(mCheckBarModes);
John Spurlockd96179e2014-08-21 16:43:45 -0400837 if (mDozeServiceHost != null) {
Jason Monkc06fbb12016-01-08 14:12:18 -0500838 mDozeServiceHost.firePowerSaveChanged(isPowerSave);
John Spurlockd96179e2014-08-21 16:43:45 -0400839 }
John Spurlock0ff62e02014-07-22 16:15:08 -0400840 }
841 @Override
842 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
843 // noop
844 }
845 });
Jason Monk30d80042015-05-08 16:54:18 -0400846 mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monkfd57ea72016-04-29 13:37:58 -0400847 mNetworkController.setUserSetupComplete(mUserSetup);
Jason Monk51e4dc02014-07-22 12:00:47 -0400848 mHotspotController = new HotspotControllerImpl(mContext);
Jason Monk4ae97d32014-12-17 10:14:33 -0500849 mBluetoothController = new BluetoothControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monk3d5f5512014-07-25 11:17:28 -0400850 mSecurityController = new SecurityControllerImpl(mContext);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400851 if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) {
852 mRotationLockController = new RotationLockControllerImpl(mContext);
John Spurlock8ab172e2013-12-19 16:39:23 -0500853 }
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200854 mUserInfoController = new UserInfoController(mContext);
John Spurlock86005342014-05-23 11:58:00 -0400855 mVolumeComponent = getComponent(VolumeComponent.class);
John Spurlockf2565a82014-10-23 20:16:22 -0400856 if (mVolumeComponent != null) {
857 mZenModeController = mVolumeComponent.getZenController();
858 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400859 mCastController = new CastControllerImpl(mContext);
Xiaohui Chen10942302015-12-16 16:38:13 -0800860
861 initSignalCluster(mStatusBarView);
862 initSignalCluster(mKeyguardStatusBar);
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400863
Adrian Roosb83777b2014-06-30 15:11:53 +0200864 mFlashlightController = new FlashlightController(mContext);
Adrian Roos1e1d6ac2014-07-22 17:18:55 +0200865 mKeyguardBottomArea.setFlashlightController(mFlashlightController);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200866 mKeyguardBottomArea.setPhoneStatusBar(this);
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700867 mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200868 mAccessibilityController = new AccessibilityController(mContext);
869 mKeyguardBottomArea.setAccessibilityController(mAccessibilityController);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200870 mNextAlarmController = new NextAlarmController(mContext);
Jorim Jaggi86905582016-02-09 21:36:09 -0800871 mLightStatusBarController = new LightStatusBarController(mIconController,
872 mBatteryController);
Jason Monk8a3a9642015-06-05 11:01:30 -0400873 mKeyguardMonitor = new KeyguardMonitor(mContext);
Fyodor Kupolovcd86ebf2015-09-29 17:06:50 -0700874 if (UserManager.get(mContext).isUserSwitcherEnabled()) {
Adrian Roos88b11932015-07-22 14:59:48 -0700875 mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
Sudheer Shanka1c7cda82015-12-31 14:46:02 +0000876 mHandler, this);
Rakesh Iyer2790a372016-01-22 15:33:39 -0800877 createUserSwitcher();
Adrian Roos2b154a92014-11-17 15:18:39 +0100878 }
Adrian Roos723632e2014-07-23 21:13:21 +0200879
John Spurlockaf8d6c42014-05-07 17:49:08 -0400880 // Set up the quick settings tile panel
Clara Bayarri9b1fdff2016-04-21 14:28:47 +0100881 AutoReinflateContainer container = (AutoReinflateContainer) mStatusBarWindow.findViewById(
882 R.id.qs_auto_reinflate_container);
Jason Monk46dbfb42016-02-25 14:59:20 -0500883 if (container != null) {
Xiaohui Chen311b98e2016-03-30 11:55:54 -0700884 final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,
John Spurlockaf8d6c42014-05-07 17:49:08 -0400885 mBluetoothController, mLocationController, mRotationLockController,
Jason Monk51e4dc02014-07-22 12:00:47 -0400886 mNetworkController, mZenModeController, mHotspotController,
John Spurlock657c62c2014-07-22 12:18:09 -0400887 mCastController, mFlashlightController,
Jason Monkabe19742015-09-29 09:47:06 -0400888 mUserSwitcherController, mUserInfoController, mKeyguardMonitor,
Jason Monk46dbfb42016-02-25 14:59:20 -0500889 mSecurityController, mBatteryController, mIconController,
890 mNextAlarmController);
Adrian Roos5fd872e2014-08-12 17:28:58 +0200891 mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
Jason Monk46dbfb42016-02-25 14:59:20 -0500892 container.addInflateListener(new InflateListener() {
John Spurlockbceed062014-08-10 18:04:16 -0400893 @Override
Jason Monk46dbfb42016-02-25 14:59:20 -0500894 public void onInflated(View v) {
895 QSContainer qsContainer = (QSContainer) v.findViewById(
896 R.id.quick_settings_container);
897 qsContainer.setHost(qsh);
898 mQSPanel = qsContainer.getQsPanel();
899 mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
Kaori Katouccf08d72015-05-26 16:25:04 +0900900 mKeyguardStatusBar.setQSPanel(mQSPanel);
Jason Monk46dbfb42016-02-25 14:59:20 -0500901 mHeader = qsContainer.getHeader();
902 initSignalCluster(mHeader);
903 mHeader.setActivityStarter(PhoneStatusBar.this);
John Spurlockbceed062014-08-10 18:04:16 -0400904 }
905 });
Siva Velusamy537421b2012-09-14 14:45:02 -0700906 }
907
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200908 // User info. Trigger first load.
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200909 mKeyguardStatusBar.setUserInfoController(mUserInfoController);
Adrian Roosffc90972015-06-09 18:09:49 -0700910 mKeyguardStatusBar.setUserSwitcherController(mUserSwitcherController);
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200911 mUserInfoController.reloadUserInfo();
912
Jorim Jaggi708f7722014-08-20 17:30:38 +0200913 ((BatteryMeterView) mStatusBarView.findViewById(R.id.battery)).setBatteryController(
914 mBatteryController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200915 mKeyguardStatusBar.setBatteryController(mBatteryController);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200916
John Spurlock56d007b2013-10-28 18:40:56 -0400917 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
918 mBroadcastReceiver.onReceive(mContext,
919 new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
Selim Cinek372d1bd2015-08-14 13:19:37 -0700920 mGestureWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
921 "GestureWakeLock");
Selim Cinek69ff8af2015-08-25 19:03:48 -0700922 mVibrator = mContext.getSystemService(Vibrator.class);
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700923
Joe Onorato808182d2010-07-09 18:52:06 -0400924 // receive broadcasts
925 IntentFilter filter = new IntentFilter();
Joe Onorato808182d2010-07-09 18:52:06 -0400926 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
927 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -0400928 filter.addAction(Intent.ACTION_SCREEN_ON);
Kenny Guy44fc65f2014-11-28 22:18:14 +0000929 context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
Joe Onorato808182d2010-07-09 18:52:06 -0400930
Adrian Roos8e3e8362015-07-16 19:42:22 -0700931 IntentFilter demoFilter = new IntentFilter();
932 if (DEBUG_MEDIA_FAKE_ARTWORK) {
933 demoFilter.addAction(ACTION_FAKE_ARTWORK);
934 }
935 demoFilter.addAction(ACTION_DEMO);
936 context.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
937 android.Manifest.permission.DUMP, null);
938
John Spurlock919adac2012-10-02 16:41:12 -0400939 // listen for USER_SETUP_COMPLETE setting (per-user)
940 resetUserSetupObserver();
941
Chris Craik2507c342015-05-04 14:36:49 -0700942 // disable profiling bars, since they overlap and clutter the output on app windows
943 ThreadedRenderer.overrideProperty("disableProfileBars", "true");
944
945 // Private API call to make the shadows look better for Recents
946 ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
947
Daniel Sandlera310af82012-04-24 01:20:13 -0400948 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -0400949 }
950
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700951 protected BatteryController createBatteryController() {
952 return new BatteryControllerImpl(mContext);
953 }
954
Selim Cinek3e7592d2016-04-11 09:35:54 +0800955 private void inflateOverflowContainer() {
956 mKeyguardIconOverflowContainer =
957 (NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
958 R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
959 mKeyguardIconOverflowContainer.setOnActivatedListener(this);
960 mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
961 mStackScroller.setOverflowContainer(mKeyguardIconOverflowContainer);
962 }
963
Selim Cinek01af3342016-02-09 19:25:31 -0800964 @Override
Selim Cinek3e7592d2016-04-11 09:35:54 +0800965 protected void onDensityOrFontScaleChanged() {
966 super.onDensityOrFontScaleChanged();
967 mScrimController.onDensityOrFontScaleChanged();
968 mStatusBarView.onDensityOrFontScaleChanged();
Adrian Roosd390b892016-05-05 10:50:49 -0400969 if (mBrightnessMirrorController != null) {
970 mBrightnessMirrorController.onDensityOrFontScaleChanged();
971 }
Selim Cinek3e7592d2016-04-11 09:35:54 +0800972 inflateSignalClusters();
973 mIconController.onDensityOrFontScaleChanged();
Selim Cinek01af3342016-02-09 19:25:31 -0800974 inflateDismissView();
975 updateClearAll();
976 inflateEmptyShadeView();
977 updateEmptyShadeView();
Selim Cinek3e7592d2016-04-11 09:35:54 +0800978 inflateOverflowContainer();
Selim Cinekaa8bbf12016-05-04 14:13:20 -0700979 mStatusBarKeyguardViewManager.onDensityOrFontScaleChanged();
Adrian Roosd390b892016-05-05 10:50:49 -0400980 mUserInfoController.onDensityOrFontScaleChanged();
981 if (mUserSwitcherController != null) {
982 mUserSwitcherController.onDensityOrFontScaleChanged();
983 }
984 if (mKeyguardUserSwitcher != null) {
985 mKeyguardUserSwitcher.onDensityOrFontScaleChanged();
986 }
Selim Cinek3e7592d2016-04-11 09:35:54 +0800987 }
988
989 private void inflateSignalClusters() {
990 SignalClusterView signalClusterView = reinflateSignalCluster(mStatusBarView);
991 mIconController.setSignalCluster(signalClusterView);
992 reinflateSignalCluster(mKeyguardStatusView);
993 }
994
995 private SignalClusterView reinflateSignalCluster(View view) {
996 SignalClusterView signalCluster =
997 (SignalClusterView) view.findViewById(R.id.signal_cluster);
998 if (signalCluster != null) {
999 ViewParent parent = signalCluster.getParent();
1000 if (parent instanceof ViewGroup) {
1001 ViewGroup viewParent = (ViewGroup) parent;
1002 int index = viewParent.indexOfChild(signalCluster);
1003 viewParent.removeView(signalCluster);
1004 SignalClusterView newCluster = (SignalClusterView) LayoutInflater.from(mContext)
1005 .inflate(R.layout.signal_cluster_view, viewParent, false);
1006 ViewGroup.MarginLayoutParams layoutParams =
1007 (ViewGroup.MarginLayoutParams) viewParent.getLayoutParams();
1008 layoutParams.setMarginsRelative(
1009 mContext.getResources().getDimensionPixelSize(
1010 R.dimen.signal_cluster_margin_start),
1011 0, 0, 0);
1012 newCluster.setLayoutParams(layoutParams);
1013 newCluster.setSecurityController(mSecurityController);
1014 newCluster.setNetworkController(mNetworkController);
1015 viewParent.addView(newCluster, index);
1016 return newCluster;
1017 }
1018 return signalCluster;
1019 }
1020 return null;
Selim Cinek01af3342016-02-09 19:25:31 -08001021 }
1022
1023 private void inflateEmptyShadeView() {
1024 mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
1025 R.layout.status_bar_no_notifications, mStackScroller, false);
1026 mStackScroller.setEmptyShadeView(mEmptyShadeView);
1027 }
1028
1029 private void inflateDismissView() {
1030 mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
1031 R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
1032 mDismissView.setOnButtonClickListener(new View.OnClickListener() {
1033 @Override
1034 public void onClick(View v) {
1035 MetricsLogger.action(mContext, MetricsEvent.ACTION_DISMISS_ALL_NOTES);
1036 clearAllNotifications();
1037 }
1038 });
1039 mStackScroller.setDismissView(mDismissView);
1040 }
1041
Rakesh Iyer2790a372016-01-22 15:33:39 -08001042 protected void createUserSwitcher() {
1043 mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
1044 (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
1045 mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
1046 }
1047
Xiaohui Chend839d1a2016-01-21 13:05:02 -08001048 protected void inflateStatusBarWindow(Context context) {
1049 mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
1050 R.layout.super_status_bar, null);
1051 }
1052
Rakesh Iyer1186faa2015-12-07 16:48:46 -08001053 protected void createNavigationBarView(Context context) {
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -08001054 inflateNavigationBarView(context);
Rakesh Iyer1186faa2015-12-07 16:48:46 -08001055 mNavigationBarView.setDisabledFlags(mDisabled1);
1056 mNavigationBarView.setComponents(mRecents, getComponent(Divider.class));
1057 mNavigationBarView.setOnVerticalChangedListener(
1058 new NavigationBarView.OnVerticalChangedListener() {
1059 @Override
1060 public void onVerticalChanged(boolean isVertical) {
1061 if (mAssistManager != null) {
1062 mAssistManager.onConfigurationChanged();
1063 }
1064 mNotificationPanel.setQsScrimEnabled(!isVertical);
1065 }
1066 });
1067 mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
1068 @Override
1069 public boolean onTouch(View v, MotionEvent event) {
1070 checkUserAutohide(v, event);
1071 return false;
1072 }});
1073 }
1074
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -08001075 protected void inflateNavigationBarView(Context context) {
Jason Monk4f878ef2016-01-23 14:37:38 -05001076 mNavigationBarView = (NavigationBarView) View.inflate(
1077 context, R.layout.navigation_bar, null);
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -08001078 }
1079
1080 protected void initSignalCluster(View containerView) {
Xiaohui Chen10942302015-12-16 16:38:13 -08001081 SignalClusterView signalCluster =
1082 (SignalClusterView) containerView.findViewById(R.id.signal_cluster);
1083 if (signalCluster != null) {
Xiaohui Chen10942302015-12-16 16:38:13 -08001084 signalCluster.setSecurityController(mSecurityController);
1085 signalCluster.setNetworkController(mNetworkController);
1086 }
1087 }
1088
Muyuan Lic510b5e2016-03-09 17:15:05 -08001089 public void clearAllNotifications() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001090
1091 // animate-swipe all dismissable notifications, then animate the shade closed
1092 int numChildren = mStackScroller.getChildCount();
1093
1094 final ArrayList<View> viewsToHide = new ArrayList<View>(numChildren);
1095 for (int i = 0; i < numChildren; i++) {
1096 final View child = mStackScroller.getChildAt(i);
Selim Cinekb5605e52015-02-20 18:21:41 +01001097 if (child instanceof ExpandableNotificationRow) {
1098 if (mStackScroller.canChildBeDismissed(child)) {
1099 if (child.getVisibility() == View.VISIBLE) {
1100 viewsToHide.add(child);
1101 }
1102 }
1103 ExpandableNotificationRow row = (ExpandableNotificationRow) child;
1104 List<ExpandableNotificationRow> children = row.getNotificationChildren();
1105 if (row.areChildrenExpanded() && children != null) {
1106 for (ExpandableNotificationRow childRow : children) {
1107 if (childRow.getVisibility() == View.VISIBLE) {
1108 viewsToHide.add(childRow);
1109 }
1110 }
Dan Sandlereceda3d2014-07-21 15:35:01 -04001111 }
1112 }
1113 }
1114 if (viewsToHide.isEmpty()) {
1115 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
1116 return;
1117 }
1118
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001119 addPostCollapseAction(new Runnable() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001120 @Override
1121 public void run() {
Selim Cinek9c17b772015-07-07 20:37:09 -07001122 mStackScroller.setDismissAllInProgress(false);
Dan Sandlereceda3d2014-07-21 15:35:01 -04001123 try {
1124 mBarService.onClearAllNotifications(mCurrentUserId);
1125 } catch (Exception ex) { }
1126 }
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001127 });
Dan Sandlereceda3d2014-07-21 15:35:01 -04001128
1129 performDismissAllAnimations(viewsToHide);
1130
1131 }
1132
1133 private void performDismissAllAnimations(ArrayList<View> hideAnimatedList) {
1134 Runnable animationFinishAction = new Runnable() {
1135 @Override
1136 public void run() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001137 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
1138 }
1139 };
1140
1141 // let's disable our normal animations
1142 mStackScroller.setDismissAllInProgress(true);
1143
1144 // Decrease the delay for every row we animate to give the sense of
1145 // accelerating the swipes
1146 int rowDelayDecrement = 10;
1147 int currentDelay = 140;
Selim Cinek7d5f3742014-11-07 18:07:49 +01001148 int totalDelay = 180;
Dan Sandlereceda3d2014-07-21 15:35:01 -04001149 int numItems = hideAnimatedList.size();
Selim Cinek7d5f3742014-11-07 18:07:49 +01001150 for (int i = numItems - 1; i >= 0; i--) {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001151 View view = hideAnimatedList.get(i);
1152 Runnable endRunnable = null;
Selim Cinek7d5f3742014-11-07 18:07:49 +01001153 if (i == 0) {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001154 endRunnable = animationFinishAction;
1155 }
1156 mStackScroller.dismissViewAnimated(view, endRunnable, totalDelay, 260);
1157 currentDelay = Math.max(50, currentDelay - rowDelayDecrement);
1158 totalDelay += currentDelay;
1159 }
1160 }
1161
John Spurlockae641c92014-06-30 18:11:40 -04001162 @Override
1163 protected void setZenMode(int mode) {
1164 super.setZenMode(mode);
1165 if (mIconPolicy != null) {
1166 mIconPolicy.setZenMode(mode);
1167 }
1168 }
1169
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001170 protected void startKeyguard() {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001171 KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001172 mFingerprintUnlockController = new FingerprintUnlockController(mContext,
1173 mStatusBarWindowManager, mDozeScrimController, keyguardViewMediator,
1174 mScrimController, this);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001175 mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001176 getBouncerContainer(), mStatusBarWindowManager, mScrimController,
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001177 mFingerprintUnlockController);
Selim Cinekcfafe4e2015-08-11 14:58:44 -07001178 mKeyguardIndicationController.setStatusBarKeyguardViewManager(
1179 mStatusBarKeyguardViewManager);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001180 mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
Nicolas Prevot1dbbe7d2016-05-17 12:52:54 +01001181 mIconPolicy.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
Adrian Roosd28ccd72016-01-06 15:23:14 +01001182 mRemoteInputController.addCallback(mStatusBarKeyguardViewManager);
Adrian Roosc0a579e2016-03-30 16:43:58 -07001183
1184 if (FORCE_REMOTE_INPUT_HISTORY) {
1185 mRemoteInputController.addCallback(new RemoteInputController.Callback() {
1186 @Override
1187 public void onRemoteInputSent(Entry entry) {
1188 if (mKeysKeptForRemoteInput.contains(entry.key)) {
1189 removeNotification(entry.key, null);
1190 }
1191 }
1192 });
1193 }
1194
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001195 mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
Jorim Jaggi86905582016-02-09 21:36:09 -08001196 mLightStatusBarController.setFingerprintUnlockController(mFingerprintUnlockController);
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001197 }
1198
Michael Jurka7f2668c2012-03-27 07:49:52 -07001199 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -07001200 protected View getStatusBarView() {
1201 return mStatusBarView;
1202 }
1203
Jorim Jaggi0a27be82014-06-11 03:22:39 +02001204 public StatusBarWindowView getStatusBarWindow() {
1205 return mStatusBarWindow;
1206 }
1207
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001208 protected ViewGroup getBouncerContainer() {
1209 return mStatusBarWindow;
1210 }
1211
Joe Onoratodc100302011-01-11 17:07:41 -08001212 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -04001213 if (mNaturalBarHeight < 0) {
1214 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -07001215 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -04001216 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
1217 }
1218 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -08001219 }
1220
Daniel Sandler5c8da942011-06-28 00:29:04 -04001221 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
1222 public void onClick(View v) {
John Spurlockc8b46ca2013-04-08 12:59:26 -04001223 awakenDreams();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001224 toggleRecentApps();
1225 }
1226 };
Chris Wren0c8275b2012-05-08 13:36:48 -04001227
Jorim Jaggi75b25972015-10-21 14:51:10 +02001228 private View.OnLongClickListener mLongPressBackListener = new View.OnLongClickListener() {
Jason Monk62515be2014-05-21 16:06:19 -04001229 @Override
1230 public boolean onLongClick(View v) {
Jorim Jaggi75b25972015-10-21 14:51:10 +02001231 return handleLongPressBack();
1232 }
1233 };
1234
1235 private View.OnLongClickListener mRecentsLongClickListener = new View.OnLongClickListener() {
1236
1237 @Override
1238 public boolean onLongClick(View v) {
Jorim Jaggi19cf2972016-04-07 23:26:10 -07001239 if (mRecents == null || !ActivityManager.supportsMultiWindow()
1240 || !getComponent(Divider.class).getView().getSnapAlgorithm()
1241 .isSplitScreenFeasible()) {
Phil Weaver315c34e2016-02-19 15:12:29 -08001242 return false;
1243 }
Winsonc694a502016-03-10 16:35:03 -08001244
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001245 toggleSplitScreenMode(MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS,
1246 MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS);
1247 return true;
Jason Monk62515be2014-05-21 16:06:19 -04001248 }
1249 };
1250
Phil Weaver315c34e2016-02-19 15:12:29 -08001251 @Override
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001252 protected void toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction) {
Phil Weaver315c34e2016-02-19 15:12:29 -08001253 if (mRecents == null) {
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001254 return;
Phil Weaver315c34e2016-02-19 15:12:29 -08001255 }
1256 int dockSide = WindowManagerProxy.getInstance().getDockSide();
1257 if (dockSide == WindowManager.DOCKED_INVALID) {
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001258 mRecents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE,
1259 ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, null, metricsDockAction);
Phil Weaver315c34e2016-02-19 15:12:29 -08001260 } else {
1261 EventBus.getDefault().send(new UndockingTaskEvent());
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001262 if (metricsUndockAction != -1) {
1263 MetricsLogger.action(mContext, metricsUndockAction);
1264 }
Phil Weaver315c34e2016-02-19 15:12:29 -08001265 }
1266 }
1267
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001268 private final View.OnLongClickListener mLongPressHomeListener
1269 = new View.OnLongClickListener() {
1270 @Override
1271 public boolean onLongClick(View v) {
1272 if (shouldDisableNavbarGestures()) {
1273 return false;
1274 }
Chris Wrenf6e9228b2016-01-26 18:04:35 -05001275 MetricsLogger.action(mContext, MetricsEvent.ACTION_ASSIST_LONG_PRESS);
Jorim Jaggi165ce062015-07-06 16:18:11 -07001276 mAssistManager.startAssist(new Bundle() /* args */);
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001277 awakenDreams();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001278 if (mNavigationBarView != null) {
Xiyuan Xiaee7dd052015-05-15 09:46:27 -07001279 mNavigationBarView.abortCurrentGesture();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001280 }
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001281 return true;
Jim Miller9a720f52012-05-30 03:19:43 -07001282 }
1283 };
1284
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001285 private final View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
Jim Millere898ac52012-04-06 17:10:57 -07001286 public boolean onTouch(View v, MotionEvent event) {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001287 switch (event.getAction()) {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001288 case MotionEvent.ACTION_UP:
1289 case MotionEvent.ACTION_CANCEL:
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001290 awakenDreams();
1291 break;
1292 }
1293 return false;
Jim Millere898ac52012-04-06 17:10:57 -07001294 }
1295 };
Daniel Sandler5c8da942011-06-28 00:29:04 -04001296
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001297 private void awakenDreams() {
1298 if (mDreamManager != null) {
1299 try {
1300 mDreamManager.awaken();
1301 } catch (RemoteException e) {
1302 // fine, stay asleep then
1303 }
1304 }
1305 }
1306
Michael Jurka412cba82011-10-17 09:05:00 -07001307 private void prepareNavigationBarView() {
1308 mNavigationBarView.reorient();
1309
Jason Monka2081822016-01-18 14:41:03 -05001310 ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton();
1311 recentsButton.setOnClickListener(mRecentsClickListener);
1312 recentsButton.setOnTouchListener(mRecentsPreloadOnTouchListener);
1313 recentsButton.setLongClickable(true);
1314 recentsButton.setOnLongClickListener(mRecentsLongClickListener);
Anthony Chenada13042016-01-19 16:57:20 -08001315
Jason Monka2081822016-01-18 14:41:03 -05001316 ButtonDispatcher backButton = mNavigationBarView.getBackButton();
1317 backButton.setLongClickable(true);
1318 backButton.setOnLongClickListener(mLongPressBackListener);
Anthony Chenada13042016-01-19 16:57:20 -08001319
Jason Monka2081822016-01-18 14:41:03 -05001320 ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
1321 homeButton.setOnTouchListener(mHomeActionListener);
1322 homeButton.setOnLongClickListener(mLongPressHomeListener);
Anthony Chenada13042016-01-19 16:57:20 -08001323
Selim Cineke70d6532015-04-24 16:46:13 -07001324 mAssistManager.onConfigurationChanged();
Michael Jurka412cba82011-10-17 09:05:00 -07001325 }
1326
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001327 // For small-screen devices (read: phones) that lack hardware navigation buttons
Rakesh Iyer1186faa2015-12-07 16:48:46 -08001328 protected void addNavigationBar() {
John Spurlockcd686b52013-06-05 10:13:46 -04001329 if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -04001330 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001331
Michael Jurka412cba82011-10-17 09:05:00 -07001332 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001333
Jeff Brown98365d72012-08-19 20:30:52 -07001334 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001335 }
1336
Victor Chanecdb8b02016-01-07 18:32:43 -08001337 protected void repositionNavigationBar() {
John Spurlock56d007b2013-10-28 18:40:56 -04001338 if (mNavigationBarView == null || !mNavigationBarView.isAttachedToWindow()) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001339
Michael Jurka412cba82011-10-17 09:05:00 -07001340 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001341
Jeff Brown98365d72012-08-19 20:30:52 -07001342 mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001343 }
1344
John Spurlock1bbd49d2012-10-19 11:09:32 -04001345 private void notifyNavigationBarScreenOn(boolean screenOn) {
1346 if (mNavigationBarView == null) return;
1347 mNavigationBarView.notifyScreenOn(screenOn);
1348 }
1349
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001350 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001351 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -07001352 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001353 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
1354 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001355 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
1356 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -07001357 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -04001358 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jim Millerd99e7fd2012-05-08 16:30:42 -07001359 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
John Spurlockad3e6cb2013-04-30 08:47:43 -04001360 PixelFormat.TRANSLUCENT);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001361 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -07001362 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001363 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
1364 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001365
1366 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001367 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001368 return lp;
1369 }
1370
Jason Monk07473ce2016-01-05 14:59:19 -05001371 @Override
1372 public void setIcon(String slot, StatusBarIcon icon) {
1373 mIconController.setIcon(slot, icon);
Joe Onorato808182d2010-07-09 18:52:06 -04001374 }
1375
Jason Monk07473ce2016-01-05 14:59:19 -05001376 @Override
1377 public void removeIcon(String slot) {
1378 mIconController.removeIcon(slot);
Joe Onorato808182d2010-07-09 18:52:06 -04001379 }
1380
John Spurlockbf20eab2014-04-09 16:40:39 -04001381 public UserHandle getCurrentUserHandle() {
1382 return new UserHandle(mCurrentUserId);
1383 }
1384
Christoph Studer71f18fd2014-05-20 17:02:04 +02001385 @Override
Selim Cinek379ff8f2015-02-20 17:03:16 +01001386 public void addNotification(StatusBarNotification notification, RankingMap ranking,
1387 Entry oldEntry) {
Chris Wrenaaa58d12014-06-03 14:29:12 -04001388 if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
Chris Wrend4db6cb2013-08-07 16:05:23 -04001389
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001390 mNotificationData.updateRanking(ranking);
Selim Cinek8d490d42015-04-10 00:05:50 -07001391 Entry shadeEntry = createNotificationViews(notification);
Chris Wrena4ef6202014-06-09 18:07:30 -04001392 if (shadeEntry == null) {
1393 return;
1394 }
Chris Wrenbdf33762015-12-04 15:50:51 -05001395 boolean isHeadsUped = mUseHeadsUp && shouldPeek(shadeEntry);
Selim Cinek31d9ef72015-04-15 19:29:49 -07001396 if (isHeadsUped) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001397 mHeadsUpManager.showNotification(shadeEntry);
Amith Yamasanif47e51e2015-04-17 10:02:15 -07001398 // Mark as seen immediately
1399 setNotificationShown(notification);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001400 }
Chris Wrena4ef6202014-06-09 18:07:30 -04001401
Selim Cinek31d9ef72015-04-15 19:29:49 -07001402 if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
Julia Reynoldsd5607292016-02-05 15:25:58 -05001403 if (shouldSuppressFullScreenIntent(notification.getKey())) {
Julia Reynolds61721582016-01-05 08:35:25 -05001404 if (DEBUG) {
1405 Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + notification.getKey());
1406 }
Julia Reynoldsf0f629f2016-02-25 09:34:04 -05001407 } else if (mNotificationData.getImportance(notification.getKey())
1408 < NotificationListenerService.Ranking.IMPORTANCE_MAX) {
1409 if (DEBUG) {
1410 Log.d(TAG, "No Fullscreen intent: not important enough: "
1411 + notification.getKey());
1412 }
Julia Reynolds61721582016-01-05 08:35:25 -05001413 } else {
1414 // Stop screensaver if the notification has a full-screen intent.
1415 // (like an incoming phone call)
1416 awakenDreams();
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -04001417
Julia Reynolds61721582016-01-05 08:35:25 -05001418 // not immersive & a full-screen alert should be shown
1419 if (DEBUG)
1420 Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
1421 try {
1422 EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
1423 notification.getKey());
1424 notification.getNotification().fullScreenIntent.send();
1425 shadeEntry.notifyFullScreenIntentLaunched();
1426 MetricsLogger.count(mContext, "note_fullscreen", 1);
1427 } catch (PendingIntent.CanceledException e) {
1428 }
John Spurlockbf20eab2014-04-09 16:40:39 -04001429 }
Joe Onorato808182d2010-07-09 18:52:06 -04001430 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001431 addNotificationViews(shadeEntry, ranking);
Joe Onorato808182d2010-07-09 18:52:06 -04001432 // Recalculate the position of the sliding windows and the titles.
1433 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001434 }
1435
Julia Reynoldsd5607292016-02-05 15:25:58 -05001436 private boolean shouldSuppressFullScreenIntent(String key) {
Dan Sandlerdc34df52016-04-07 21:04:46 -04001437 if (isDeviceInVrMode()) {
1438 return true;
1439 }
1440
Julia Reynolds0971cb02016-01-26 17:00:22 -05001441 if (mPowerManager.isInteractive()) {
Julia Reynolds0971cb02016-01-26 17:00:22 -05001442 return mNotificationData.shouldSuppressScreenOn(key);
Julia Reynoldsd5607292016-02-05 15:25:58 -05001443 } else {
1444 return mNotificationData.shouldSuppressScreenOff(key);
Julia Reynolds0971cb02016-01-26 17:00:22 -05001445 }
1446 }
1447
Chris Wren51c75102013-07-16 20:49:17 -04001448 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001449 protected void updateNotificationRanking(RankingMap ranking) {
Chris Wren333a61c2014-05-28 16:40:57 -04001450 mNotificationData.updateRanking(ranking);
Chris Wren333a61c2014-05-28 16:40:57 -04001451 updateNotifications();
1452 }
1453
1454 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001455 public void removeNotification(String key, RankingMap ranking) {
Selim Cinek684a4422015-04-15 16:18:39 -07001456 boolean deferRemoval = false;
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001457 if (mHeadsUpManager.isHeadsUp(key)) {
Adrian Roosc721fcc52016-04-29 11:28:37 -07001458 // A cancel() in repsonse to a remote input shouldn't be delayed, as it makes the
1459 // sending look longer than it takes.
1460 boolean ignoreEarliestRemovalTime = mRemoteInputController.isSpinning(key)
1461 && !FORCE_REMOTE_INPUT_HISTORY;
1462 deferRemoval = !mHeadsUpManager.removeNotification(key, ignoreEarliestRemovalTime);
Chris Wrena4ef6202014-06-09 18:07:30 -04001463 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001464 if (key.equals(mMediaNotificationKey)) {
1465 clearCurrentMediaNotification();
Adrian Roos52738322016-01-29 08:49:21 -08001466 updateMediaMetaData(true, true);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001467 }
Adrian Roosc0a579e2016-03-30 16:43:58 -07001468 if (FORCE_REMOTE_INPUT_HISTORY && mRemoteInputController.isSpinning(key)) {
1469 Entry entry = mNotificationData.get(key);
1470 StatusBarNotification sbn = entry.notification;
1471
1472 Notification.Builder b = Notification.Builder
1473 .recoverBuilder(mContext, sbn.getNotification().clone());
1474 CharSequence[] oldHistory = sbn.getNotification().extras
1475 .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
1476 CharSequence[] newHistory;
1477 if (oldHistory == null) {
1478 newHistory = new CharSequence[1];
1479 } else {
1480 newHistory = new CharSequence[oldHistory.length + 1];
1481 for (int i = 0; i < oldHistory.length; i++) {
1482 newHistory[i + 1] = oldHistory[i];
1483 }
1484 }
1485 newHistory[0] = String.valueOf(entry.remoteInputText);
1486 b.setRemoteInputHistory(newHistory);
1487
1488 Notification newNotification = b.build();
1489
1490 // Undo any compatibility view inflation
1491 newNotification.contentView = sbn.getNotification().contentView;
1492 newNotification.bigContentView = sbn.getNotification().bigContentView;
1493 newNotification.headsUpContentView = sbn.getNotification().headsUpContentView;
1494
1495 StatusBarNotification newSbn = new StatusBarNotification(sbn.getPackageName(),
1496 sbn.getOpPkg(),
1497 sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(),
1498 0, newNotification, sbn.getUser(), sbn.getPostTime());
1499
1500 updateNotification(newSbn, null);
1501 mKeysKeptForRemoteInput.add(entry.key);
1502 return;
1503 }
Selim Cinek684a4422015-04-15 16:18:39 -07001504 if (deferRemoval) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001505 mLatestRankingMap = ranking;
1506 mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
1507 return;
1508 }
Selim Cineka5703182016-05-11 21:23:16 -04001509 Entry entry = mNotificationData.get(key);
1510 if (entry != null && entry.row != null) {
1511 entry.row.setRemoved(true);
1512 }
Selim Cinek3f19f602016-05-02 18:01:56 -07001513 // Let's remove the children if this was a summary
1514 handleGroupSummaryRemoved(key, ranking);
Christoph Studer37fe6932014-05-26 13:10:30 +02001515 StatusBarNotification old = removeNotificationViews(key, ranking);
John Spurlockcd686b52013-06-05 10:13:46 -04001516 if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -04001517
1518 if (old != null) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001519 if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
Jorim Jaggiba94f882014-08-20 19:23:55 +02001520 && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02001521 if (mState == StatusBarState.SHADE) {
1522 animateCollapsePanels();
1523 } else if (mState == StatusBarState.SHADE_LOCKED) {
1524 goToKeyguard();
1525 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -04001526 }
Joe Onorato808182d2010-07-09 18:52:06 -04001527 }
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001528 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001529 }
1530
Selim Cinek3f19f602016-05-02 18:01:56 -07001531 /**
1532 * Ensures that the group children are cancelled immediately when the group summary is cancelled
1533 * instead of waiting for the notification manager to send all cancels. Otherwise this could
1534 * lead to flickers.
1535 *
1536 * This also ensures that the animation looks nice and only consists of a single disappear
1537 * animation instead of multiple.
1538 *
1539 * @param key the key of the notification was removed
1540 * @param ranking the current ranking
1541 */
1542 private void handleGroupSummaryRemoved(String key,
1543 RankingMap ranking) {
1544 Entry entry = mNotificationData.get(key);
1545 if (entry != null && entry.row != null
1546 && entry.row.isSummaryWithChildren()) {
1547 if (entry.notification.getOverrideGroupKey() != null && !entry.row.isDismissed()) {
1548 // We don't want to remove children for autobundled notifications as they are not
1549 // always cancelled. We only remove them if they were dismissed by the user.
1550 return;
1551 }
Selim Cinek3f19f602016-05-02 18:01:56 -07001552 List<ExpandableNotificationRow> notificationChildren =
1553 entry.row.getNotificationChildren();
1554 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>(notificationChildren);
1555 for (int i = 0; i < toRemove.size(); i++) {
1556 toRemove.get(i).setKeepInParent(true);
Selim Cineka5703182016-05-11 21:23:16 -04001557 // we need to set this state earlier as otherwise we might generate some weird
1558 // animations
Selim Cinekfa760d42016-05-10 15:50:53 -04001559 toRemove.get(i).setRemoved(true);
Selim Cinek3f19f602016-05-02 18:01:56 -07001560 }
1561 for (int i = 0; i < toRemove.size(); i++) {
1562 removeNotification(toRemove.get(i).getStatusBarNotification().getKey(), ranking);
Selim Cinek7103fd42016-05-09 22:22:33 -04001563 // we need to ensure that the view is actually properly removed from the viewstate
1564 // as this won't happen anymore when kept in the parent.
1565 mStackScroller.removeViewStateForView(toRemove.get(i));
Selim Cinek3f19f602016-05-02 18:01:56 -07001566 }
1567 }
1568 }
1569
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001570 @Override
1571 protected void refreshLayout(int layoutDirection) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001572 if (mNavigationBarView != null) {
1573 mNavigationBarView.setLayoutDirection(layoutDirection);
1574 }
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001575 }
1576
Christoph Studer37fe6932014-05-26 13:10:30 +02001577 private void updateNotificationShade() {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001578 if (mStackScroller == null) return;
Daniel Sandler26cda272012-05-22 15:44:08 -04001579
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001580 // Do not modify the notifications during collapse.
1581 if (isCollapsing()) {
1582 addPostCollapseAction(new Runnable() {
1583 @Override
1584 public void run() {
1585 updateNotificationShade();
1586 }
1587 });
1588 return;
1589 }
1590
Christoph Studerc8db24b2014-07-25 17:50:30 +02001591 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
Jorim Jaggif6411742014-08-05 17:10:43 +00001592 ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size());
Christoph Studerc8db24b2014-07-25 17:50:30 +02001593 final int N = activeNotifications.size();
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001594 for (int i=0; i<N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001595 Entry ent = activeNotifications.get(i);
1596 int vis = ent.notification.getNotification().visibility;
Kenny Guy3a7c4a52014-03-03 18:24:03 +00001597
Christoph Studerc8db24b2014-07-25 17:50:30 +02001598 // Display public version of the notification if we need to redact.
Jorim Jaggiae441282014-08-01 02:45:18 +02001599 final boolean hideSensitive =
1600 !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId());
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001601 boolean sensitiveNote = vis == Notification.VISIBILITY_PRIVATE;
1602 boolean sensitivePackage = packageHasVisibilityOverride(ent.notification.getKey());
1603 boolean sensitive = (sensitiveNote && hideSensitive) || sensitivePackage;
1604 boolean showingPublic = sensitive && isLockscreenPublicMode();
Sudheer Shankaf5b850e2016-01-25 19:58:59 +00001605 if (showingPublic) {
1606 updatePublicContentView(ent, ent.notification);
1607 }
Selim Cinek3c76d502016-02-19 15:16:33 -08001608 ent.row.setSensitive(sensitive, hideSensitive);
Dan Sandler1b718782014-07-18 12:43:45 -04001609 if (ent.autoRedacted && ent.legacy) {
Jorim Jaggiae441282014-08-01 02:45:18 +02001610 // TODO: Also fade this? Or, maybe easier (and better), provide a dark redacted form
1611 // for legacy auto redacted notifications.
Dan Sandler1b718782014-07-18 12:43:45 -04001612 if (showingPublic) {
1613 ent.row.setShowingLegacyBackground(false);
1614 } else {
1615 ent.row.setShowingLegacyBackground(true);
1616 }
1617 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001618 if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
1619 ExpandableNotificationRow summary = mGroupManager.getGroupSummary(
1620 ent.row.getStatusBarNotification());
1621 List<ExpandableNotificationRow> orderedChildren =
1622 mTmpChildOrderMap.get(summary);
1623 if (orderedChildren == null) {
1624 orderedChildren = new ArrayList<>();
1625 mTmpChildOrderMap.put(summary, orderedChildren);
1626 }
1627 orderedChildren.add(ent.row);
1628 } else {
1629 toShow.add(ent.row);
1630 }
1631
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001632 }
1633
Selim Cinekef5127e2015-12-21 16:55:58 -08001634 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001635 for (int i=0; i< mStackScroller.getChildCount(); i++) {
1636 View child = mStackScroller.getChildAt(i);
Jorim Jaggif6411742014-08-05 17:10:43 +00001637 if (!toShow.contains(child) && child instanceof ExpandableNotificationRow) {
Selim Cinekef5127e2015-12-21 16:55:58 -08001638 toRemove.add((ExpandableNotificationRow) child);
Joe Onorato808182d2010-07-09 18:52:06 -04001639 }
1640 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001641
Selim Cinekef5127e2015-12-21 16:55:58 -08001642 for (ExpandableNotificationRow remove : toRemove) {
1643 if (mGroupManager.isChildInGroupWithSummary(remove.getStatusBarNotification())) {
1644 // we are only transfering this notification to its parent, don't generate an animation
1645 mStackScroller.setChildTransferInProgress(true);
1646 }
Selim Cinekc1e389d2016-04-07 11:02:57 -07001647 if (remove.isSummaryWithChildren()) {
1648 remove.removeAllChildren();
1649 }
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001650 mStackScroller.removeView(remove);
Selim Cinekef5127e2015-12-21 16:55:58 -08001651 mStackScroller.setChildTransferInProgress(false);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001652 }
Selim Cinek2b542422016-03-04 18:10:37 -08001653
1654 removeNotificationChildren();
1655
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001656 for (int i=0; i<toShow.size(); i++) {
1657 View v = toShow.get(i);
1658 if (v.getParent() == null) {
Christoph Studer37fe6932014-05-26 13:10:30 +02001659 mStackScroller.addView(v);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001660 }
1661 }
Daniel Sandler26cda272012-05-22 15:44:08 -04001662
Selim Cinek2b542422016-03-04 18:10:37 -08001663 addNotificationChildrenAndSort();
1664
Christoph Studer37fe6932014-05-26 13:10:30 +02001665 // So after all this work notifications still aren't sorted correctly.
1666 // Let's do that now by advancing through toShow and mStackScroller in
1667 // lock-step, making sure mStackScroller matches what we see in toShow.
1668 int j = 0;
1669 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1670 View child = mStackScroller.getChildAt(i);
1671 if (!(child instanceof ExpandableNotificationRow)) {
1672 // We don't care about non-notification views.
1673 continue;
1674 }
1675
Selim Cinekb5605e52015-02-20 18:21:41 +01001676 ExpandableNotificationRow targetChild = toShow.get(j);
1677 if (child != targetChild) {
1678 // Oops, wrong notification at this position. Put the right one
1679 // here and advance both lists.
1680 mStackScroller.changeViewPosition(targetChild, i);
Christoph Studer37fe6932014-05-26 13:10:30 +02001681 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001682 j++;
Selim Cinekb5605e52015-02-20 18:21:41 +01001683
Christoph Studer37fe6932014-05-26 13:10:30 +02001684 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001685
Selim Cinekb5605e52015-02-20 18:21:41 +01001686 // clear the map again for the next usage
1687 mTmpChildOrderMap.clear();
1688
Christoph Studer37fe6932014-05-26 13:10:30 +02001689 updateRowStates();
Jorim Jaggif6411742014-08-05 17:10:43 +00001690 updateSpeedbump();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001691 updateClearAll();
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001692 updateEmptyShadeView();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001693
Benjamin Franz27cf1462015-04-23 19:36:42 +01001694 updateQsExpansionEnabled();
1695 mShadeUpdates.check();
1696 }
1697
1698 /**
1699 * Disable QS if device not provisioned.
1700 * If the user switcher is simple then disable QS during setup because
1701 * the user intends to use the lock screen user switcher, QS in not needed.
1702 */
1703 private void updateQsExpansionEnabled() {
Jason Monk3ad242d2014-09-15 11:13:35 -04001704 mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned()
Adrian Roos2b154a92014-11-17 15:18:39 +01001705 && (mUserSetup || mUserSwitcherController == null
Benjamin Franz27cf1462015-04-23 19:36:42 +01001706 || !mUserSwitcherController.isSimpleUserSwitcher())
Adrian Roos21d2a252015-06-01 13:59:59 -07001707 && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
1708 && !ONLY_CORE_APPS);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001709 }
1710
Selim Cinek2b542422016-03-04 18:10:37 -08001711 private void addNotificationChildrenAndSort() {
Selim Cinek322ec7e2016-02-11 14:47:06 -08001712 // Let's now add all notification children which are missing
1713 boolean orderChanged = false;
1714 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1715 View view = mStackScroller.getChildAt(i);
1716 if (!(view instanceof ExpandableNotificationRow)) {
1717 // We don't care about non-notification views.
1718 continue;
1719 }
1720
1721 ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
1722 List<ExpandableNotificationRow> children = parent.getNotificationChildren();
1723 List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
1724
Selim Cinekb5605e52015-02-20 18:21:41 +01001725 for (int childIndex = 0; orderedChildren != null && childIndex < orderedChildren.size();
1726 childIndex++) {
1727 ExpandableNotificationRow childView = orderedChildren.get(childIndex);
1728 if (children == null || !children.contains(childView)) {
1729 parent.addChildNotification(childView, childIndex);
1730 mStackScroller.notifyGroupChildAdded(childView);
1731 }
1732 }
1733
1734 // Finally after removing and adding has been beformed we can apply the order.
1735 orderChanged |= parent.applyChildOrder(orderedChildren);
1736 }
1737 if (orderChanged) {
1738 mStackScroller.generateChildOrderChangedEvent();
1739 }
1740 }
1741
Selim Cinek2b542422016-03-04 18:10:37 -08001742 private void removeNotificationChildren() {
1743 // First let's remove all children which don't belong in the parents
1744 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
1745 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1746 View view = mStackScroller.getChildAt(i);
1747 if (!(view instanceof ExpandableNotificationRow)) {
1748 // We don't care about non-notification views.
1749 continue;
1750 }
1751
1752 ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
1753 List<ExpandableNotificationRow> children = parent.getNotificationChildren();
1754 List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
1755
1756 if (children != null) {
1757 toRemove.clear();
1758 for (ExpandableNotificationRow childRow : children) {
Selim Cinek3f19f602016-05-02 18:01:56 -07001759 if ((orderedChildren == null
1760 || !orderedChildren.contains(childRow))
1761 && !childRow.keepInParent()) {
Selim Cinek2b542422016-03-04 18:10:37 -08001762 toRemove.add(childRow);
1763 }
1764 }
1765 for (ExpandableNotificationRow remove : toRemove) {
1766 parent.removeChildNotification(remove);
1767 if (mNotificationData.get(remove.getStatusBarNotification().getKey()) == null) {
1768 // We only want to add an animation if the view is completely removed
1769 // otherwise it's just a transfer
Selim Cinekd1395642016-04-28 12:22:42 -07001770 mStackScroller.notifyGroupChildRemoved(remove,
1771 parent.getChildrenContainer());
Selim Cinek2b542422016-03-04 18:10:37 -08001772 }
1773 }
1774 }
1775 }
1776 }
1777
Jason Monk7e53f202016-01-28 10:40:20 -05001778 @Override
1779 public void addQsTile(ComponentName tile) {
1780 mQSPanel.getHost().addTile(tile);
1781 }
1782
1783 @Override
1784 public void remQsTile(ComponentName tile) {
1785 mQSPanel.getHost().removeTile(tile);
1786 }
1787
1788 @Override
1789 public void clickTile(ComponentName tile) {
1790 mQSPanel.clickTile(tile);
1791 }
1792
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001793 private boolean packageHasVisibilityOverride(String key) {
Julia Reynolds26fa8a52016-02-24 08:31:22 -05001794 return mNotificationData.getVisibilityOverride(key) == Notification.VISIBILITY_PRIVATE;
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001795 }
1796
Dan Sandlereceda3d2014-07-21 15:35:01 -04001797 private void updateClearAll() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001798 boolean showDismissView =
1799 mState != StatusBarState.KEYGUARD &&
1800 mNotificationData.hasActiveClearableNotifications();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001801 mStackScroller.updateDismissView(showDismissView);
1802 }
1803
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001804 private void updateEmptyShadeView() {
1805 boolean showEmptyShade =
1806 mState != StatusBarState.KEYGUARD &&
1807 mNotificationData.getActiveNotifications().size() == 0;
1808 mNotificationPanel.setShadeEmpty(showEmptyShade);
1809 }
1810
Jorim Jaggif6411742014-08-05 17:10:43 +00001811 private void updateSpeedbump() {
1812 int speedbumpIndex = -1;
1813 int currentIndex = 0;
Selim Cinek2a739342016-03-17 10:28:55 -07001814 final int N = mStackScroller.getChildCount();
Jorim Jaggif6411742014-08-05 17:10:43 +00001815 for (int i = 0; i < N; i++) {
Selim Cinek2a739342016-03-17 10:28:55 -07001816 View view = mStackScroller.getChildAt(i);
1817 if (view.getVisibility() == View.GONE || !(view instanceof ExpandableNotificationRow)) {
Selim Cinekb5605e52015-02-20 18:21:41 +01001818 continue;
1819 }
Selim Cinek2a739342016-03-17 10:28:55 -07001820 ExpandableNotificationRow row = (ExpandableNotificationRow) view;
1821 if (mNotificationData.isAmbient(row.getStatusBarNotification().getKey())) {
Jorim Jaggif6411742014-08-05 17:10:43 +00001822 speedbumpIndex = currentIndex;
1823 break;
1824 }
1825 currentIndex++;
1826 }
1827 mStackScroller.updateSpeedBumpIndex(speedbumpIndex);
1828 }
1829
Selim Cinekb5605e52015-02-20 18:21:41 +01001830 public static boolean isTopLevelChild(Entry entry) {
1831 return entry.row.getParent() instanceof NotificationStackScrollLayout;
1832 }
1833
Chris Wren0c8275b2012-05-08 13:36:48 -04001834 @Override
Christoph Studer37fe6932014-05-26 13:10:30 +02001835 protected void updateNotifications() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001836 mNotificationData.filterAndSort();
1837
Christoph Studer37fe6932014-05-26 13:10:30 +02001838 updateNotificationShade();
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001839 mIconController.updateNotificationIcons(mNotificationData);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001840 }
1841
Selim Cinekef5127e2015-12-21 16:55:58 -08001842 public void requestNotificationUpdate() {
1843 updateNotifications();
1844 }
1845
Jorim Jaggi54045422014-07-03 18:30:40 +02001846 @Override
Chris Wren0c8275b2012-05-08 13:36:48 -04001847 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001848
Chris Wren6d15a362013-08-20 18:46:29 -04001849 if (SPEW) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001850 final boolean clearable = hasActiveNotifications() &&
1851 mNotificationData.hasActiveClearableNotifications();
1852 Log.d(TAG, "setAreThereNotifications: N=" +
1853 mNotificationData.getActiveNotifications().size() + " any=" +
1854 hasActiveNotifications() + " clearable=" + clearable);
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001855 }
1856
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001857 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
Christoph Studerc8db24b2014-07-25 17:50:30 +02001858 final boolean showDot = hasActiveNotifications() && !areLightsOn();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001859 if (showDot != (nlo.getAlpha() == 1.0f)) {
1860 if (showDot) {
1861 nlo.setAlpha(0f);
1862 nlo.setVisibility(View.VISIBLE);
1863 }
1864 nlo.animate()
1865 .alpha(showDot?1:0)
1866 .setDuration(showDot?750:250)
1867 .setInterpolator(new AccelerateInterpolator(2.0f))
1868 .setListener(showDot ? null : new AnimatorListenerAdapter() {
1869 @Override
1870 public void onAnimationEnd(Animator _a) {
1871 nlo.setVisibility(View.GONE);
1872 }
1873 })
1874 .start();
1875 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04001876
Dan Sandler16128f42014-05-21 12:48:22 -04001877 findAndUpdateMediaNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001878 }
1879
Dan Sandler16128f42014-05-21 12:48:22 -04001880 public void findAndUpdateMediaNotifications() {
1881 boolean metaDataChanged = false;
1882
1883 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001884 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
1885 final int N = activeNotifications.size();
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001886
1887 // Promote the media notification with a controller in 'playing' state, if any.
Dan Sandler16128f42014-05-21 12:48:22 -04001888 Entry mediaNotification = null;
1889 MediaController controller = null;
Christoph Studerc8db24b2014-07-25 17:50:30 +02001890 for (int i = 0; i < N; i++) {
1891 final Entry entry = activeNotifications.get(i);
Dan Sandler16128f42014-05-21 12:48:22 -04001892 if (isMediaNotification(entry)) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001893 final MediaSession.Token token =
1894 entry.notification.getNotification().extras
Dan Sandler16128f42014-05-21 12:48:22 -04001895 .getParcelable(Notification.EXTRA_MEDIA_SESSION);
1896 if (token != null) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001897 MediaController aController = new MediaController(mContext, token);
1898 if (PlaybackState.STATE_PLAYING ==
1899 getMediaControllerPlaybackState(aController)) {
1900 if (DEBUG_MEDIA) {
1901 Log.v(TAG, "DEBUG_MEDIA: found mediastyle controller matching "
1902 + entry.notification.getKey());
1903 }
Dan Sandler16128f42014-05-21 12:48:22 -04001904 mediaNotification = entry;
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001905 controller = aController;
1906 break;
Dan Sandler16128f42014-05-21 12:48:22 -04001907 }
1908 }
1909 }
1910 }
Dan Sandler16128f42014-05-21 12:48:22 -04001911 if (mediaNotification == null) {
1912 // Still nothing? OK, let's just look for live media sessions and see if they match
1913 // one of our notifications. This will catch apps that aren't (yet!) using media
1914 // notifications.
1915
1916 if (mMediaSessionManager != null) {
1917 final List<MediaController> sessions
1918 = mMediaSessionManager.getActiveSessionsForUser(
1919 null,
1920 UserHandle.USER_ALL);
1921
1922 for (MediaController aController : sessions) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001923 if (PlaybackState.STATE_PLAYING ==
1924 getMediaControllerPlaybackState(aController)) {
1925 // now to see if we have one like this
1926 final String pkg = aController.getPackageName();
Dan Sandler16128f42014-05-21 12:48:22 -04001927
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001928 for (int i = 0; i < N; i++) {
1929 final Entry entry = activeNotifications.get(i);
1930 if (entry.notification.getPackageName().equals(pkg)) {
1931 if (DEBUG_MEDIA) {
1932 Log.v(TAG, "DEBUG_MEDIA: found controller matching "
1933 + entry.notification.getKey());
Dan Sandler16128f42014-05-21 12:48:22 -04001934 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001935 controller = aController;
1936 mediaNotification = entry;
1937 break;
Dan Sandler16128f42014-05-21 12:48:22 -04001938 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001939 }
Dan Sandler16128f42014-05-21 12:48:22 -04001940 }
1941 }
1942 }
1943 }
1944
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001945 if (controller != null && !sameSessions(mMediaController, controller)) {
Dan Sandler16128f42014-05-21 12:48:22 -04001946 // We have a new media session
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001947 clearCurrentMediaNotification();
Dan Sandler16128f42014-05-21 12:48:22 -04001948 mMediaController = controller;
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001949 mMediaController.registerCallback(mMediaListener);
1950 mMediaMetadata = mMediaController.getMetadata();
Dan Sandler16128f42014-05-21 12:48:22 -04001951 if (DEBUG_MEDIA) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001952 Log.v(TAG, "DEBUG_MEDIA: insert listener, receive metadata: "
1953 + mMediaMetadata);
Dan Sandler16128f42014-05-21 12:48:22 -04001954 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001955
1956 if (mediaNotification != null) {
1957 mMediaNotificationKey = mediaNotification.notification.getKey();
1958 if (DEBUG_MEDIA) {
1959 Log.v(TAG, "DEBUG_MEDIA: Found new media notification: key="
1960 + mMediaNotificationKey + " controller=" + mMediaController);
1961 }
1962 }
1963 metaDataChanged = true;
Dan Sandler16128f42014-05-21 12:48:22 -04001964 }
1965 }
1966
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001967 if (metaDataChanged) {
1968 updateNotifications();
1969 }
Adrian Roos52738322016-01-29 08:49:21 -08001970 updateMediaMetaData(metaDataChanged, true);
Dan Sandler16128f42014-05-21 12:48:22 -04001971 }
1972
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001973 private int getMediaControllerPlaybackState(MediaController controller) {
1974 if (controller != null) {
1975 final PlaybackState playbackState = controller.getPlaybackState();
1976 if (playbackState != null) {
1977 return playbackState.getState();
1978 }
1979 }
1980 return PlaybackState.STATE_NONE;
1981 }
1982
1983 private boolean isPlaybackActive(int state) {
1984 if (state != PlaybackState.STATE_STOPPED
1985 && state != PlaybackState.STATE_ERROR
1986 && state != PlaybackState.STATE_NONE) {
1987 return true;
1988 }
1989 return false;
1990 }
1991
1992 private void clearCurrentMediaNotification() {
1993 mMediaNotificationKey = null;
1994 mMediaMetadata = null;
1995 if (mMediaController != null) {
1996 if (DEBUG_MEDIA) {
1997 Log.v(TAG, "DEBUG_MEDIA: Disconnecting from old controller: "
1998 + mMediaController.getPackageName());
1999 }
2000 mMediaController.unregisterCallback(mMediaListener);
2001 }
2002 mMediaController = null;
2003 }
2004
Christoph Studerb5245d82014-09-19 16:54:36 +02002005 private boolean sameSessions(MediaController a, MediaController b) {
2006 if (a == b) return true;
2007 if (a == null) return false;
2008 return a.controlsSameSession(b);
2009 }
2010
Dan Sandler16128f42014-05-21 12:48:22 -04002011 /**
Dan Sandler7dea0ee2014-07-21 21:07:15 -04002012 * Hide the album artwork that is fading out and release its bitmap.
Dan Sandler16128f42014-05-21 12:48:22 -04002013 */
2014 private Runnable mHideBackdropFront = new Runnable() {
2015 @Override
2016 public void run() {
2017 if (DEBUG_MEDIA) {
2018 Log.v(TAG, "DEBUG_MEDIA: removing fade layer");
2019 }
2020 mBackdropFront.setVisibility(View.INVISIBLE);
Dan Sandler7dea0ee2014-07-21 21:07:15 -04002021 mBackdropFront.animate().cancel();
2022 mBackdropFront.setImageDrawable(null);
Dan Sandler16128f42014-05-21 12:48:22 -04002023 }
2024 };
2025
2026 /**
Adrian Roose381c162016-02-11 15:26:42 -08002027 * Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper.
Dan Sandler16128f42014-05-21 12:48:22 -04002028 */
Adrian Roos52738322016-01-29 08:49:21 -08002029 public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
Dan Sandler16128f42014-05-21 12:48:22 -04002030 if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) return;
2031
2032 if (mBackdrop == null) return; // called too early
2033
Selim Cinek37c110f2015-05-22 12:38:44 -07002034 if (mLaunchTransitionFadingAway) {
2035 mBackdrop.setVisibility(View.INVISIBLE);
2036 return;
2037 }
2038
Dan Sandler16128f42014-05-21 12:48:22 -04002039 if (DEBUG_MEDIA) {
2040 Log.v(TAG, "DEBUG_MEDIA: updating album art for notification " + mMediaNotificationKey
Selim Cinek131c1e22015-05-11 19:04:49 -07002041 + " metadata=" + mMediaMetadata
2042 + " metaDataChanged=" + metaDataChanged
2043 + " state=" + mState);
Dan Sandler16128f42014-05-21 12:48:22 -04002044 }
2045
Adrian Roos3b777cb2016-04-14 12:04:28 -07002046 Drawable artworkDrawable = null;
Dan Sandler16128f42014-05-21 12:48:22 -04002047 if (mMediaMetadata != null) {
Adrian Roos3b777cb2016-04-14 12:04:28 -07002048 Bitmap artworkBitmap = null;
Dan Sandler16128f42014-05-21 12:48:22 -04002049 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
2050 if (artworkBitmap == null) {
2051 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
2052 // might still be null
2053 }
Adrian Roos3b777cb2016-04-14 12:04:28 -07002054 if (artworkBitmap != null) {
2055 artworkDrawable = new BitmapDrawable(mBackdropBack.getResources(), artworkBitmap);
2056 }
Dan Sandler16128f42014-05-21 12:48:22 -04002057 }
Adrian Roosa3760a42016-04-25 16:21:06 -07002058 boolean allowWhenShade = false;
Adrian Roos3b777cb2016-04-14 12:04:28 -07002059 if (ENABLE_LOCKSCREEN_WALLPAPER && artworkDrawable == null) {
2060 Bitmap lockWallpaper = mLockscreenWallpaper.getBitmap();
2061 if (lockWallpaper != null) {
2062 artworkDrawable = new LockscreenWallpaper.WallpaperDrawable(
2063 mBackdropBack.getResources(), lockWallpaper);
Adrian Roosa3760a42016-04-25 16:21:06 -07002064 // We're in the SHADE mode on the SIM screen - yet we still need to show
2065 // the lockscreen wallpaper in that mode.
2066 allowWhenShade = mStatusBarKeyguardViewManager != null
2067 && mStatusBarKeyguardViewManager.isShowing();
Adrian Roos3b777cb2016-04-14 12:04:28 -07002068 }
Adrian Roos52738322016-01-29 08:49:21 -08002069 }
Dan Sandler16128f42014-05-21 12:48:22 -04002070
Adrian Roosa3760a42016-04-25 16:21:06 -07002071 boolean hideBecauseOccluded = mStatusBarKeyguardViewManager != null
2072 && mStatusBarKeyguardViewManager.isOccluded();
2073
Adrian Roos3b777cb2016-04-14 12:04:28 -07002074 final boolean hasArtwork = artworkDrawable != null;
Dan Sandler16128f42014-05-21 12:48:22 -04002075
Adrian Roosa3760a42016-04-25 16:21:06 -07002076 if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
2077 && (mState != StatusBarState.SHADE || allowWhenShade)
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002078 && mFingerprintUnlockController.getMode()
Adrian Roosa3760a42016-04-25 16:21:06 -07002079 != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
2080 && !hideBecauseOccluded) {
Dan Sandler16128f42014-05-21 12:48:22 -04002081 // time to show some art!
2082 if (mBackdrop.getVisibility() != View.VISIBLE) {
2083 mBackdrop.setVisibility(View.VISIBLE);
Adrian Roos52738322016-01-29 08:49:21 -08002084 if (allowEnterAnimation) {
Adrian Roosd5c2db62016-03-08 16:11:31 -08002085 mBackdrop.animate().alpha(1f).withEndAction(new Runnable() {
2086 @Override
2087 public void run() {
2088 mStatusBarWindowManager.setBackdropShowing(true);
2089 }
2090 });
Adrian Roos52738322016-01-29 08:49:21 -08002091 } else {
2092 mBackdrop.animate().cancel();
2093 mBackdrop.setAlpha(1f);
Adrian Roosd5c2db62016-03-08 16:11:31 -08002094 mStatusBarWindowManager.setBackdropShowing(true);
Adrian Roos52738322016-01-29 08:49:21 -08002095 }
Dan Sandler16128f42014-05-21 12:48:22 -04002096 metaDataChanged = true;
2097 if (DEBUG_MEDIA) {
2098 Log.v(TAG, "DEBUG_MEDIA: Fading in album artwork");
2099 }
2100 }
2101 if (metaDataChanged) {
2102 if (mBackdropBack.getDrawable() != null) {
Julia Reynolds4b9658a2015-07-22 17:07:42 -04002103 Drawable drawable =
Adrian Roos751f33f2016-04-19 16:41:18 -07002104 mBackdropBack.getDrawable().getConstantState()
2105 .newDrawable(mBackdropFront.getResources()).mutate();
Selim Cineka0fad3b2014-09-19 17:20:05 +02002106 mBackdropFront.setImageDrawable(drawable);
Jorim Jaggi0e664392014-09-27 01:30:22 +02002107 if (mScrimSrcModeEnabled) {
2108 mBackdropFront.getDrawable().mutate().setXfermode(mSrcOverXferMode);
2109 }
Dan Sandler16128f42014-05-21 12:48:22 -04002110 mBackdropFront.setAlpha(1f);
2111 mBackdropFront.setVisibility(View.VISIBLE);
2112 } else {
2113 mBackdropFront.setVisibility(View.INVISIBLE);
2114 }
2115
2116 if (DEBUG_MEDIA_FAKE_ARTWORK) {
2117 final int c = 0xFF000000 | (int)(Math.random() * 0xFFFFFF);
2118 Log.v(TAG, String.format("DEBUG_MEDIA: setting new color: 0x%08x", c));
2119 mBackdropBack.setBackgroundColor(0xFFFFFFFF);
2120 mBackdropBack.setImageDrawable(new ColorDrawable(c));
2121 } else {
Adrian Roos3b777cb2016-04-14 12:04:28 -07002122 mBackdropBack.setImageDrawable(artworkDrawable);
Dan Sandler16128f42014-05-21 12:48:22 -04002123 }
Jorim Jaggi0e664392014-09-27 01:30:22 +02002124 if (mScrimSrcModeEnabled) {
2125 mBackdropBack.getDrawable().mutate().setXfermode(mSrcXferMode);
2126 }
Dan Sandler16128f42014-05-21 12:48:22 -04002127
2128 if (mBackdropFront.getVisibility() == View.VISIBLE) {
2129 if (DEBUG_MEDIA) {
2130 Log.v(TAG, "DEBUG_MEDIA: Crossfading album artwork from "
2131 + mBackdropFront.getDrawable()
2132 + " to "
2133 + mBackdropBack.getDrawable());
2134 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02002135 mBackdropFront.animate()
Dan Sandler16128f42014-05-21 12:48:22 -04002136 .setDuration(250)
2137 .alpha(0f).withEndAction(mHideBackdropFront);
2138 }
2139 }
2140 } else {
2141 // need to hide the album art, either because we are unlocked or because
2142 // the metadata isn't there to support it
2143 if (mBackdrop.getVisibility() != View.GONE) {
2144 if (DEBUG_MEDIA) {
2145 Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
2146 }
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002147 if (mFingerprintUnlockController.getMode()
Adrian Roosa3760a42016-04-25 16:21:06 -07002148 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
2149 || hideBecauseOccluded) {
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02002150
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002151 // We are unlocking directly - no animation!
2152 mBackdrop.setVisibility(View.GONE);
Vadim Trysheve7d7d572016-03-09 16:44:30 -08002153 mBackdropBack.setImageDrawable(null);
Adrian Roosd5c2db62016-03-08 16:11:31 -08002154 mStatusBarWindowManager.setBackdropShowing(false);
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002155 } else {
Adrian Roosd5c2db62016-03-08 16:11:31 -08002156 mStatusBarWindowManager.setBackdropShowing(false);
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002157 mBackdrop.animate()
2158 // Never let the alpha become zero - otherwise the RenderNode
2159 // won't draw anything and uninitialized memory will show through
2160 // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in
2161 // libhwui.
2162 .alpha(0.002f)
Selim Cinekc18010f2016-01-20 13:41:30 -08002163 .setInterpolator(Interpolators.ACCELERATE_DECELERATE)
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002164 .setDuration(300)
2165 .setStartDelay(0)
2166 .withEndAction(new Runnable() {
2167 @Override
2168 public void run() {
2169 mBackdrop.setVisibility(View.GONE);
2170 mBackdropFront.animate().cancel();
Vadim Trysheve7d7d572016-03-09 16:44:30 -08002171 mBackdropBack.setImageDrawable(null);
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002172 mHandler.post(mHideBackdropFront);
2173 }
2174 });
2175 if (mKeyguardFadingAway) {
2176 mBackdrop.animate()
2177
2178 // Make it disappear faster, as the focus should be on the activity
2179 // behind.
2180 .setDuration(mKeyguardFadingAwayDuration / 2)
2181 .setStartDelay(mKeyguardFadingAwayDelay)
Selim Cinekc18010f2016-01-20 13:41:30 -08002182 .setInterpolator(Interpolators.LINEAR)
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002183 .start();
2184 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02002185 }
Dan Sandler16128f42014-05-21 12:48:22 -04002186 }
2187 }
2188 }
2189
Xiaohui Cheneb04a992016-03-22 14:58:03 -07002190 protected int adjustDisableFlags(int state) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07002191 if (!mLaunchTransitionFadingAway && !mKeyguardFadingAway
Selim Cinekbaa23272014-07-08 18:01:07 +02002192 && (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
Jorim Jaggib13d36d2014-06-06 18:03:52 +02002193 state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
2194 state |= StatusBarManager.DISABLE_SYSTEM_INFO;
2195 }
2196 return state;
2197 }
2198
Joe Onorato808182d2010-07-09 18:52:06 -04002199 /**
2200 * State is one or more of the DISABLE constants from StatusBarManager.
2201 */
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002202 public void disable(int state1, int state2, boolean animate) {
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002203 animate &= mStatusBarWindowState != WINDOW_STATE_HIDDEN;
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002204 mDisabledUnmodified1 = state1;
2205 mDisabledUnmodified2 = state2;
2206 state1 = adjustDisableFlags(state1);
2207 final int old1 = mDisabled1;
2208 final int diff1 = state1 ^ old1;
2209 mDisabled1 = state1;
2210
2211 final int old2 = mDisabled2;
2212 final int diff2 = state2 ^ old2;
2213 mDisabled2 = state2;
Joe Onorato808182d2010-07-09 18:52:06 -04002214
Daniel Sandlere21f2882011-08-18 10:14:59 -04002215 if (DEBUG) {
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002216 Log.d(TAG, String.format("disable1: 0x%08x -> 0x%08x (diff1: 0x%08x)",
2217 old1, state1, diff1));
2218 Log.d(TAG, String.format("disable2: 0x%08x -> 0x%08x (diff2: 0x%08x)",
2219 old2, state2, diff2));
Daniel Sandlere21f2882011-08-18 10:14:59 -04002220 }
2221
Daniel Sandler6da2b762011-09-14 16:04:59 -04002222 StringBuilder flagdbg = new StringBuilder();
2223 flagdbg.append("disable: < ");
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002224 flagdbg.append(((state1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
2225 flagdbg.append(((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
2226 flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
2227 flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
2228 flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
2229 flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
2230 flagdbg.append(((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
2231 flagdbg.append(((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
2232 flagdbg.append(((state1 & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
2233 flagdbg.append(((diff1 & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
2234 flagdbg.append(((state1 & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
2235 flagdbg.append(((diff1 & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
2236 flagdbg.append(((state1 & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
2237 flagdbg.append(((diff1 & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
2238 flagdbg.append(((state1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
2239 flagdbg.append(((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
2240 flagdbg.append(((state1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
2241 flagdbg.append(((diff1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
Benjamin Franz27cf1462015-04-23 19:36:42 +01002242 flagdbg.append(((state2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "QUICK_SETTINGS"
2243 : "quick_settings");
2244 flagdbg.append(((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04002245 flagdbg.append(">");
John Spurlockcd686b52013-06-05 10:13:46 -04002246 Log.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07002247
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002248 if ((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
2249 if ((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002250 mIconController.hideSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04002251 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002252 mIconController.showSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04002253 }
2254 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04002255
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002256 if ((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) {
2257 boolean visible = (state1 & StatusBarManager.DISABLE_CLOCK) == 0;
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002258 mIconController.setClockVisibility(visible);
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07002259 }
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002260 if ((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) {
2261 if ((state1 & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002262 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04002263 }
2264 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04002265
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002266 if ((diff1 & (StatusBarManager.DISABLE_HOME
Jim Miller5e6af442011-12-02 18:24:26 -08002267 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerd5483c32012-10-19 16:44:15 -04002268 | StatusBarManager.DISABLE_BACK
2269 | StatusBarManager.DISABLE_SEARCH)) != 0) {
Daniel Sandlerdba93562011-10-06 16:39:58 -04002270 // the nav bar will take care of these
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002271 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state1);
Daniel Sandler6da2b762011-09-14 16:04:59 -04002272
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002273 if ((state1 & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04002274 // close recents if it's visible
Winson Chung1e8d71b2014-05-16 17:05:22 -07002275 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
2276 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
Daniel Sandler6da2b762011-09-14 16:04:59 -04002277 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04002278 }
2279
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002280 if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
2281 if ((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002282 mIconController.hideNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04002283 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002284 mIconController.showNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04002285 }
Joe Onorato808182d2010-07-09 18:52:06 -04002286 }
Jason Monkf7019542014-07-31 12:42:25 -04002287
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002288 if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
Jason Monkf7019542014-07-31 12:42:25 -04002289 mDisableNotificationAlerts =
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002290 (state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
Jason Monkf7019542014-07-31 12:42:25 -04002291 mHeadsUpObserver.onChange(true);
2292 }
Benjamin Franz27cf1462015-04-23 19:36:42 +01002293
2294 if ((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) {
2295 updateQsExpansionEnabled();
2296 }
Joe Onorato808182d2010-07-09 18:52:06 -04002297 }
2298
Michael Jurka7f2668c2012-03-27 07:49:52 -07002299 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07002300 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07002301 return new PhoneStatusBar.H();
2302 }
2303
Jorim Jaggi97b63c42014-05-02 23:03:34 +02002304 @Override
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02002305 public void startActivity(Intent intent, boolean dismissShade) {
2306 startActivityDismissingKeyguard(intent, false, dismissShade);
Jorim Jaggi97b63c42014-05-02 23:03:34 +02002307 }
2308
Selim Cineke70d6532015-04-24 16:46:13 -07002309 @Override
Jorim Jaggid9449862015-05-29 14:49:08 -07002310 public void startActivity(Intent intent, boolean dismissShade, Callback callback) {
2311 startActivityDismissingKeyguard(intent, false, dismissShade, callback);
2312 }
2313
2314 @Override
Selim Cineke70d6532015-04-24 16:46:13 -07002315 public void preventNextAnimation() {
2316 overrideActivityPendingAppTransition(true /* keyguardShowing */);
2317 }
2318
Jorim Jaggib690f0d2014-07-03 23:25:44 +02002319 public void setQsExpanded(boolean expanded) {
2320 mStatusBarWindowManager.setQsExpanded(expanded);
Adrian Roos4c7d9602015-06-10 13:44:48 -07002321 mKeyguardStatusView.setImportantForAccessibility(expanded
2322 ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
2323 : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
Jorim Jaggib690f0d2014-07-03 23:25:44 +02002324 }
2325
Jorim Jaggi84a3e7a2014-08-13 17:58:58 +02002326 public boolean isGoingToNotificationShade() {
2327 return mLeaveOpenOnKeyguardHide;
2328 }
2329
Jorim Jaggid692dd02014-08-14 20:57:42 +02002330 public boolean isQsExpanded() {
2331 return mNotificationPanel.isQsExpanded();
2332 }
2333
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07002334 public boolean isWakeUpComingFromTouch() {
2335 return mWakeUpComingFromTouch;
Selim Cinek29ed3c92014-09-23 20:44:35 +02002336 }
2337
Selim Cinek19c8c702014-08-25 22:09:19 +02002338 public boolean isFalsingThresholdNeeded() {
Selim Cinek9db71052015-04-24 18:54:30 -07002339 return getBarState() == StatusBarState.KEYGUARD;
Selim Cinek19c8c702014-08-25 22:09:19 +02002340 }
2341
John Spurlock0b99ea92014-10-01 15:32:22 -04002342 public boolean isDozing() {
2343 return mDozing;
2344 }
2345
Christoph Studer2e731b52014-08-22 16:01:51 +02002346 @Override // NotificationData.Environment
2347 public String getCurrentMediaNotificationKey() {
2348 return mMediaNotificationKey;
2349 }
2350
Jorim Jaggi0e664392014-09-27 01:30:22 +02002351 public boolean isScrimSrcModeEnabled() {
2352 return mScrimSrcModeEnabled;
2353 }
2354
Joe Onorato808182d2010-07-09 18:52:06 -04002355 /**
Christoph Studer2231c6e2014-12-19 12:40:13 +01002356 * To be called when there's a state change in StatusBarKeyguardViewManager.
2357 */
2358 public void onKeyguardViewManagerStatesUpdated() {
2359 logStateToEventlog();
2360 }
2361
2362 @Override // UnlockMethodCache.OnUnlockMethodChangedListener
2363 public void onUnlockMethodStateChanged() {
2364 logStateToEventlog();
2365 }
2366
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002367 @Override
John Spurlockb349af572015-04-29 12:24:19 -04002368 public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
Selim Cinek684a4422015-04-15 16:18:39 -07002369 if (inPinnedMode) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002370 mStatusBarWindowManager.setHeadsUpShowing(true);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002371 mStatusBarWindowManager.setForceStatusBarVisible(true);
Selim Cinek131c1e22015-05-11 19:04:49 -07002372 if (mNotificationPanel.isFullyCollapsed()) {
2373 // We need to ensure that the touchable region is updated before the window will be
2374 // resized, in order to not catch any touches. A layout will ensure that
2375 // onComputeInternalInsets will be called and after that we can resize the layout. Let's
2376 // make sure that the window stays small for one frame until the touchableRegion is set.
2377 mNotificationPanel.requestLayout();
2378 mStatusBarWindowManager.setForceWindowCollapsed(true);
2379 mNotificationPanel.post(new Runnable() {
2380 @Override
2381 public void run() {
2382 mStatusBarWindowManager.setForceWindowCollapsed(false);
2383 }
2384 });
2385 }
Selim Cinek737bff32015-05-08 16:08:35 -07002386 } else {
Selim Cinek131c1e22015-05-11 19:04:49 -07002387 if (!mNotificationPanel.isFullyCollapsed() || mNotificationPanel.isTracking()) {
2388 // We are currently tracking or is open and the shade doesn't need to be kept
2389 // open artificially.
Selim Cinek737bff32015-05-08 16:08:35 -07002390 mStatusBarWindowManager.setHeadsUpShowing(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002391 } else {
Selim Cinek131c1e22015-05-11 19:04:49 -07002392 // we need to keep the panel open artificially, let's wait until the animation
2393 // is finished.
Selim Cinek737bff32015-05-08 16:08:35 -07002394 mHeadsUpManager.setHeadsUpGoingAway(true);
2395 mStackScroller.runAfterAnimationFinished(new Runnable() {
2396 @Override
2397 public void run() {
2398 if (!mHeadsUpManager.hasPinnedHeadsUp()) {
2399 mStatusBarWindowManager.setHeadsUpShowing(false);
2400 mHeadsUpManager.setHeadsUpGoingAway(false);
2401 }
2402 }
2403 });
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002404 }
2405 }
2406 }
2407
2408 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002409 public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
John Spurlockb349af572015-04-29 12:24:19 -04002410 dismissVolumeDialog();
Selim Cinek1f3f5442015-04-10 17:54:46 -07002411 }
2412
2413 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002414 public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
2415 }
2416
2417 @Override
2418 public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002419 if (!isHeadsUp && mHeadsUpEntriesToRemoveOnSwitch.contains(entry)) {
2420 removeNotification(entry.key, mLatestRankingMap);
2421 mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
2422 if (mHeadsUpEntriesToRemoveOnSwitch.isEmpty()) {
2423 mLatestRankingMap = null;
2424 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07002425 } else {
2426 updateNotificationRanking(null);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002427 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07002428
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002429 }
2430
Chris Wrenbdf33762015-12-04 15:50:51 -05002431 protected void updateHeadsUp(String key, Entry entry, boolean shouldPeek,
Selim Cinek29fa89b2015-04-17 10:39:11 -07002432 boolean alertAgain) {
2433 final boolean wasHeadsUp = isHeadsUp(key);
2434 if (wasHeadsUp) {
Chris Wrenbdf33762015-12-04 15:50:51 -05002435 if (!shouldPeek) {
Selim Cinek29fa89b2015-04-17 10:39:11 -07002436 // We don't want this to be interrupting anymore, lets remove it
Adrian Roosc721fcc52016-04-29 11:28:37 -07002437 mHeadsUpManager.removeNotification(key, false /* ignoreEarliestRemovalTime */);
Selim Cinek684a4422015-04-15 16:18:39 -07002438 } else {
2439 mHeadsUpManager.updateNotification(entry, alertAgain);
Selim Cinek29fa89b2015-04-17 10:39:11 -07002440 }
Chris Wrenbdf33762015-12-04 15:50:51 -05002441 } else if (shouldPeek && alertAgain) {
Selim Cinek29fa89b2015-04-17 10:39:11 -07002442 // This notification was updated to be a heads-up, show it!
2443 mHeadsUpManager.showNotification(entry);
2444 }
2445 }
2446
2447 protected void setHeadsUpUser(int newUserId) {
2448 if (mHeadsUpManager != null) {
2449 mHeadsUpManager.setUser(newUserId);
2450 }
2451 }
2452
2453 public boolean isHeadsUp(String key) {
2454 return mHeadsUpManager.isHeadsUp(key);
2455 }
2456
2457 protected boolean isSnoozedPackage(StatusBarNotification sbn) {
2458 return mHeadsUpManager.isSnoozed(sbn.getPackageName());
2459 }
2460
Selim Cineke70d6532015-04-24 16:46:13 -07002461 public boolean isKeyguardCurrentlySecure() {
Selim Cineke8bae622015-07-15 13:24:06 -07002462 return !mUnlockMethodCache.canSkipBouncer();
Selim Cineke70d6532015-04-24 16:46:13 -07002463 }
2464
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002465 public void setPanelExpanded(boolean isExpanded) {
2466 mStatusBarWindowManager.setPanelExpanded(isExpanded);
2467 }
2468
Adrian Roos401caae2016-03-04 13:35:21 -08002469 public void onScreenTurnedOff() {
2470 mFalsingManager.onScreenOff();
2471 }
2472
Christoph Studer2231c6e2014-12-19 12:40:13 +01002473 /**
Joe Onorato808182d2010-07-09 18:52:06 -04002474 * All changes to the status bar and notifications funnel through here and are batched.
2475 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07002476 private class H extends BaseStatusBar.H {
Joe Onorato808182d2010-07-09 18:52:06 -04002477 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07002478 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04002479 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002480 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04002481 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002482 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04002483 case MSG_OPEN_SETTINGS_PANEL:
Jason Monka9927322015-12-13 16:22:37 -05002484 animateExpandSettingsPanel((String) m.obj);
Daniel Sandler11cf1782012-09-27 14:03:08 -04002485 break;
2486 case MSG_CLOSE_PANELS:
2487 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002488 break;
Jorim Jaggi826730a2014-12-08 21:05:13 +01002489 case MSG_LAUNCH_TRANSITION_TIMEOUT:
2490 onLaunchTransitionTimeout();
2491 break;
Chris Wrene97f90b2013-08-07 17:39:35 -04002492 }
2493 }
2494 }
2495
Chris Wren930ecca2014-11-12 17:43:41 -05002496 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002497 public void maybeEscalateHeadsUp() {
Selim Cinek3362c132016-02-11 15:43:03 -08002498 Collection<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getAllEntries();
Selim Cineka59ecc32015-04-07 10:51:49 -07002499 for (HeadsUpManager.HeadsUpEntry entry : entries) {
2500 final StatusBarNotification sbn = entry.entry.notification;
Chris Wrene97f90b2013-08-07 17:39:35 -04002501 final Notification notification = sbn.getNotification();
2502 if (notification.fullScreenIntent != null) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002503 if (DEBUG) {
Chris Wrene97f90b2013-08-07 17:39:35 -04002504 Log.d(TAG, "converting a heads up to fullScreen");
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002505 }
Chris Wrene97f90b2013-08-07 17:39:35 -04002506 try {
Chris Wren223c66b62014-11-10 16:00:09 -05002507 EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
2508 sbn.getKey());
Chris Wrene97f90b2013-08-07 17:39:35 -04002509 notification.fullScreenIntent.send();
Selim Cinekb18a20f2015-06-04 17:08:35 +02002510 entry.entry.notifyFullScreenIntentLaunched();
Chris Wrene97f90b2013-08-07 17:39:35 -04002511 } catch (PendingIntent.CanceledException e) {
2512 }
Joe Onorato808182d2010-07-09 18:52:06 -04002513 }
2514 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002515 mHeadsUpManager.releaseAllImmediately();
Joe Onorato808182d2010-07-09 18:52:06 -04002516 }
2517
John Spurlock97642182013-07-29 17:58:39 -04002518 boolean panelsEnabled() {
Adrian Roos21d2a252015-06-01 13:59:59 -07002519 return (mDisabled1 & StatusBarManager.DISABLE_EXPAND) == 0 && !ONLY_CORE_APPS;
John Spurlock97642182013-07-29 17:58:39 -04002520 }
2521
Jorim Jaggifa505a72014-04-28 20:04:11 +02002522 void makeExpandedVisible(boolean force) {
John Spurlockcd686b52013-06-05 10:13:46 -04002523 if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
Jorim Jaggifa505a72014-04-28 20:04:11 +02002524 if (!force && (mExpandedVisible || !panelsEnabled())) {
Joe Onorato808182d2010-07-09 18:52:06 -04002525 return;
2526 }
Jim Millera073e572012-05-23 17:03:27 -07002527
Joe Onorato808182d2010-07-09 18:52:06 -04002528 mExpandedVisible = true;
John Spurlockd5ef5462012-06-13 11:19:51 -04002529 if (mNavigationBarView != null)
2530 mNavigationBarView.setSlippery(true);
Joe Onorato808182d2010-07-09 18:52:06 -04002531
Daniel Sandlera310af82012-04-24 01:20:13 -04002532 // Expand the window to encompass the full screen in anticipation of the drag.
2533 // 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 -07002534 mStatusBarWindowManager.setPanelVisible(true);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002535
2536 visibilityChanged(true);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07002537 mWaitingForKeyguardExit = false;
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002538 disable(mDisabledUnmodified1, mDisabledUnmodified2, !force /* animate */);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002539 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2540 }
2541
Daniel Sandler11cf1782012-09-27 14:03:08 -04002542 public void animateCollapsePanels() {
2543 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07002544 }
2545
John Spurlockaf8d6c42014-05-07 17:49:08 -04002546 private final Runnable mAnimateCollapsePanels = new Runnable() {
2547 @Override
2548 public void run() {
2549 animateCollapsePanels();
2550 }
2551 };
2552
2553 public void postAnimateCollapsePanels() {
2554 mHandler.post(mAnimateCollapsePanels);
2555 }
2556
Jason Monkba2318e2015-12-08 09:04:23 -05002557 public void postAnimateOpenPanels() {
2558 mHandler.sendEmptyMessage(MSG_OPEN_SETTINGS_PANEL);
2559 }
2560
Daniel Sandler11cf1782012-09-27 14:03:08 -04002561 public void animateCollapsePanels(int flags) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002562 animateCollapsePanels(flags, false /* force */, false /* delayed */,
2563 1.0f /* speedUpFactor */);
Jorim Jaggi34250762014-07-03 23:51:19 +02002564 }
2565
2566 public void animateCollapsePanels(int flags, boolean force) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002567 animateCollapsePanels(flags, force, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002568 }
2569
2570 public void animateCollapsePanels(int flags, boolean force, boolean delayed) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002571 animateCollapsePanels(flags, force, delayed, 1.0f /* speedUpFactor */);
2572 }
2573
2574 public void animateCollapsePanels(int flags, boolean force, boolean delayed,
2575 float speedUpFactor) {
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07002576 if (!force && mState != StatusBarState.SHADE) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002577 runPostCollapseRunnables();
Jorim Jaggic1cf1ae2014-05-02 21:19:17 +02002578 return;
2579 }
Joe Onorato808182d2010-07-09 18:52:06 -04002580 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04002581 Log.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04002582 + " mExpandedVisible=" + mExpandedVisible
Jim Miller9a720f52012-05-30 03:19:43 -07002583 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04002584 }
2585
Jim Miller9a720f52012-05-30 03:19:43 -07002586 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Winson Chungcdcd4872014-08-05 18:00:13 -07002587 if (!mHandler.hasMessages(MSG_HIDE_RECENT_APPS)) {
2588 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
2589 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
2590 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07002591 }
Jim Miller9a720f52012-05-30 03:19:43 -07002592
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002593 if (mStatusBarWindow != null) {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002594 // release focus immediately to kick off focus change transition
2595 mStatusBarWindowManager.setStatusBarFocusable(false);
2596
John Spurlockab847cf2014-01-15 14:13:59 -05002597 mStatusBarWindow.cancelExpandHelper();
Xiaohui Chen9f967112016-01-07 14:14:06 -08002598 mStatusBarView.collapsePanel(true /* animate */, delayed, speedUpFactor);
John Spurlockab847cf2014-01-15 14:13:59 -05002599 }
Joe Onorato808182d2010-07-09 18:52:06 -04002600 }
2601
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002602 private void runPostCollapseRunnables() {
Selim Cinekae77f8e2015-07-07 18:43:59 -07002603 ArrayList<Runnable> clonedList = new ArrayList<>(mPostCollapseRunnables);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002604 mPostCollapseRunnables.clear();
Selim Cinekae77f8e2015-07-07 18:43:59 -07002605 int size = clonedList.size();
2606 for (int i = 0; i < size; i++) {
2607 clonedList.get(i).run();
2608 }
2609
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002610 }
2611
Daniel Sandler08d05e32012-08-08 16:39:54 -04002612 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04002613 public void animateExpandNotificationsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04002614 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002615 if (!panelsEnabled()) {
Joe Onorato808182d2010-07-09 18:52:06 -04002616 return ;
2617 }
Joe Onorato808182d2010-07-09 18:52:06 -04002618
Oren Blasberg8d3fea12015-07-10 14:21:44 -07002619 mNotificationPanel.expand(true /* animate */);
Joe Onorato808182d2010-07-09 18:52:06 -04002620
2621 if (false) postStartTracing();
2622 }
2623
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002624 @Override
Jason Monka9927322015-12-13 16:22:37 -05002625 public void animateExpandSettingsPanel(String subPanel) {
John Spurlockcd686b52013-06-05 10:13:46 -04002626 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002627 if (!panelsEnabled()) {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002628 return;
2629 }
2630
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05002631 // Settings are not available in setup
2632 if (!mUserSetup) return;
2633
Jason Monka9927322015-12-13 16:22:37 -05002634
2635 if (subPanel != null) {
2636 mQSPanel.openDetails(subPanel);
2637 }
Jason Monk3c68ca22015-01-30 11:30:29 -05002638 mNotificationPanel.expandWithQs();
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002639
2640 if (false) postStartTracing();
2641 }
2642
2643 public void animateCollapseQuickSettings() {
Jorim Jaggi449981b2014-10-03 14:24:55 -07002644 if (mState == StatusBarState.SHADE) {
Xiaohui Chen9f967112016-01-07 14:14:06 -08002645 mStatusBarView.collapsePanel(true, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi449981b2014-10-03 14:24:55 -07002646 }
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002647 }
2648
Daniel Sandler08d05e32012-08-08 16:39:54 -04002649 void makeExpandedInvisible() {
John Spurlockcd686b52013-06-05 10:13:46 -04002650 if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04002651 + " mExpandedVisible=" + mExpandedVisible);
2652
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002653 if (!mExpandedVisible || mStatusBarWindow == null) {
Joe Onorato808182d2010-07-09 18:52:06 -04002654 return;
2655 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002656
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04002657 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
Xiaohui Chen9f967112016-01-07 14:14:06 -08002658 mStatusBarView.collapsePanel(/*animate=*/ false, false /* delayed*/,
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002659 1.0f /* speedUpFactor */);
Daniel Sandlered930e52012-07-03 14:31:22 -04002660
Jorim Jaggid7daab72014-05-06 22:22:20 +02002661 mNotificationPanel.closeQs();
Daniel Sandler040c2e42012-10-17 00:56:33 -04002662
Joe Onorato808182d2010-07-09 18:52:06 -04002663 mExpandedVisible = false;
John Spurlockd5ef5462012-06-13 11:19:51 -04002664 if (mNavigationBarView != null)
2665 mNavigationBarView.setSlippery(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002666 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04002667
2668 // Shrink the window to the size of the status bar only
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002669 mStatusBarWindowManager.setPanelVisible(false);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002670 mStatusBarWindowManager.setForceStatusBarVisible(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002671
Daniel Sandler469e96e2012-05-04 15:56:19 -04002672 // Close any "App info" popups that might have snuck on-screen
2673 dismissPopups();
2674
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002675 runPostCollapseRunnables();
John Spurlockcfc359a2013-09-05 10:42:03 -04002676 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002677 showBouncer();
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002678 disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
Jorim Jaggi786afcb2014-09-25 02:41:29 +02002679
2680 // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in
2681 // the bouncer appear animation.
2682 if (!mStatusBarKeyguardViewManager.isShowing()) {
2683 WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
2684 }
Joe Onorato808182d2010-07-09 18:52:06 -04002685 }
2686
Daniel Sandlerb17a7262012-10-05 14:32:50 -04002687 public boolean interceptTouchEvent(MotionEvent event) {
Chris Wren64161cc2012-12-17 16:49:30 -05002688 if (DEBUG_GESTURES) {
2689 if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
2690 EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002691 event.getActionMasked(), (int) event.getX(), (int) event.getY(),
2692 mDisabled1, mDisabled2);
Chris Wren64161cc2012-12-17 16:49:30 -05002693 }
2694
2695 }
2696
Joe Onorato808182d2010-07-09 18:52:06 -04002697 if (SPEW) {
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002698 Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled1="
2699 + mDisabled1 + " mDisabled2=" + mDisabled2 + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002700 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002701 if (event.getAction() != MotionEvent.ACTION_MOVE) {
John Spurlockcd686b52013-06-05 10:13:46 -04002702 Log.d(TAG, String.format(
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002703 "panel: %s at (%f, %f) mDisabled1=0x%08x mDisabled2=0x%08x",
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002704 MotionEvent.actionToString(event.getAction()),
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002705 event.getRawX(), event.getRawY(), mDisabled1, mDisabled2));
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002706 }
Joe Onorato808182d2010-07-09 18:52:06 -04002707 }
2708
Daniel Sandler151f00d2012-10-02 22:33:08 -04002709 if (DEBUG_GESTURES) {
2710 mGestureRec.add(event);
2711 }
Daniel Sandler33805342012-07-23 15:45:12 -04002712
John Spurlock686820a2013-09-03 14:44:16 -04002713 if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
John Spurlock5fee8362013-09-12 10:34:33 -04002714 final boolean upOrCancel =
2715 event.getAction() == MotionEvent.ACTION_UP ||
2716 event.getAction() == MotionEvent.ACTION_CANCEL;
2717 if (upOrCancel && !mExpandedVisible) {
2718 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
2719 } else {
2720 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2721 }
John Spurlock686820a2013-09-03 14:44:16 -04002722 }
Joe Onorato808182d2010-07-09 18:52:06 -04002723 return false;
2724 }
2725
Daniel Sandler08d05e32012-08-08 16:39:54 -04002726 public GestureRecorder getGestureRecorder() {
2727 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07002728 }
2729
John Spurlock56d007b2013-10-28 18:40:56 -04002730 private void setNavigationIconHints(int hints) {
Daniel Sandler328310c2011-09-23 15:56:52 -04002731 if (hints == mNavigationIconHints) return;
2732
2733 mNavigationIconHints = hints;
2734
2735 if (mNavigationBarView != null) {
2736 mNavigationBarView.setNavigationIconHints(hints);
2737 }
John Spurlockd4e65752013-08-28 14:17:09 -04002738 checkBarModes();
Daniel Sandler328310c2011-09-23 15:56:52 -04002739 }
2740
2741 @Override // CommandQueue
John Spurlock97642182013-07-29 17:58:39 -04002742 public void setWindowState(int window, int state) {
John Spurlockd4e65752013-08-28 14:17:09 -04002743 boolean showing = state == WINDOW_STATE_SHOWING;
John Spurlock97642182013-07-29 17:58:39 -04002744 if (mStatusBarWindow != null
2745 && window == StatusBarManager.WINDOW_STATUS_BAR
2746 && mStatusBarWindowState != state) {
2747 mStatusBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002748 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
Jorim Jaggi449981b2014-10-03 14:24:55 -07002749 if (!showing && mState == StatusBarState.SHADE) {
Xiaohui Chen9f967112016-01-07 14:14:06 -08002750 mStatusBarView.collapsePanel(false /* animate */, false /* delayed */,
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002751 1.0f /* speedUpFactor */);
John Spurlock97642182013-07-29 17:58:39 -04002752 }
2753 }
2754 if (mNavigationBarView != null
2755 && window == StatusBarManager.WINDOW_NAVIGATION_BAR
2756 && mNavigationBarWindowState != state) {
2757 mNavigationBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002758 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
John Spurlock97642182013-07-29 17:58:39 -04002759 }
2760 }
2761
John Spurlock97642182013-07-29 17:58:39 -04002762 @Override // CommandQueue
John Spurlockcad57682014-07-26 17:09:56 -04002763 public void buzzBeepBlinked() {
2764 if (mDozeServiceHost != null) {
2765 mDozeServiceHost.fireBuzzBeepBlinked();
2766 }
2767 }
2768
John Spurlockcb566aa2014-08-03 22:58:28 -04002769 @Override
2770 public void notificationLightOff() {
2771 if (mDozeServiceHost != null) {
2772 mDozeServiceHost.fireNotificationLight(false);
2773 }
2774 }
2775
2776 @Override
2777 public void notificationLightPulse(int argb, int onMillis, int offMillis) {
2778 if (mDozeServiceHost != null) {
2779 mDozeServiceHost.fireNotificationLight(true);
2780 }
2781 }
2782
John Spurlockcad57682014-07-26 17:09:56 -04002783 @Override // CommandQueue
Jorim Jaggi86905582016-02-09 21:36:09 -08002784 public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
2785 int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002786 final int oldVal = mSystemUiVisibility;
2787 final int newVal = (oldVal&~mask) | (vis&mask);
2788 final int diff = newVal ^ oldVal;
John Spurlockcd686b52013-06-05 10:13:46 -04002789 if (DEBUG) Log.d(TAG, String.format(
John Spurlockdcf4f212013-05-21 17:19:53 -04002790 "setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",
2791 Integer.toHexString(vis), Integer.toHexString(mask),
2792 Integer.toHexString(oldVal), Integer.toHexString(newVal),
2793 Integer.toHexString(diff)));
Jorim Jaggi86905582016-02-09 21:36:09 -08002794 boolean sbModeChanged = false;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002795 if (diff != 0) {
Winson Chung9214eff2014-06-12 13:59:25 -07002796 // we never set the recents bit via this method, so save the prior state to prevent
2797 // clobbering the bit below
2798 final boolean wasRecentsVisible = (mSystemUiVisibility & View.RECENT_APPS_VISIBLE) > 0;
2799
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002800 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04002801
John Spurlocke1f366f2013-08-05 12:22:40 -04002802 // update low profile
2803 if ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
John Spurlock7edfbca2013-09-14 11:58:55 -04002804 setAreThereNotifications();
Daniel Sandler60ee2562011-07-22 12:34:33 -04002805 }
2806
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002807 // ready to unhide
2808 if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
2809 mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
2810 mNoAnimationOnNextBarModeChange = true;
2811 }
2812
John Spurlocke1f366f2013-08-05 12:22:40 -04002813 // update status bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04002814 final int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002815 View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT,
2816 View.STATUS_BAR_TRANSPARENT);
John Spurlocke1f366f2013-08-05 12:22:40 -04002817
2818 // update navigation bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04002819 final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
John Spurlockf6b63972013-08-27 16:08:28 -04002820 oldVal, newVal, mNavigationBarView.getBarTransitions(),
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002821 View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,
2822 View.NAVIGATION_BAR_TRANSPARENT);
Jorim Jaggi86905582016-02-09 21:36:09 -08002823 sbModeChanged = sbMode != -1;
John Spurlockd4e65752013-08-28 14:17:09 -04002824 final boolean nbModeChanged = nbMode != -1;
2825 boolean checkBarModes = false;
2826 if (sbModeChanged && sbMode != mStatusBarMode) {
2827 mStatusBarMode = sbMode;
2828 checkBarModes = true;
2829 }
2830 if (nbModeChanged && nbMode != mNavigationBarMode) {
2831 mNavigationBarMode = nbMode;
2832 checkBarModes = true;
2833 }
2834 if (checkBarModes) {
2835 checkBarModes();
2836 }
2837 if (sbModeChanged || nbModeChanged) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002838 // update transient bar autohide
John Spurlockc6d1c602014-01-17 15:22:06 -05002839 if (mStatusBarMode == MODE_SEMI_TRANSPARENT || mNavigationBarMode == MODE_SEMI_TRANSPARENT) {
John Spurlock32beb2c2013-03-11 10:16:47 -04002840 scheduleAutohide();
2841 } else {
John Spurlock32beb2c2013-03-11 10:16:47 -04002842 cancelAutohide();
2843 }
2844 }
John Spurlocke1f366f2013-08-05 12:22:40 -04002845
John Spurlock5b9145b2013-08-20 15:13:47 -04002846 if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
2847 mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
2848 }
2849
Winson Chung9214eff2014-06-12 13:59:25 -07002850 // restore the recents bit
2851 if (wasRecentsVisible) {
2852 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
2853 }
2854
John Spurlocke1f366f2013-08-05 12:22:40 -04002855 // send updated sysui visibility to window manager
John Spurlock32beb2c2013-03-11 10:16:47 -04002856 notifyUiVisibilityChanged(mSystemUiVisibility);
Joe Onorato93056472010-09-10 10:30:46 -04002857 }
Jorim Jaggi86905582016-02-09 21:36:09 -08002858
2859 mLightStatusBarController.onSystemUiVisibilityChanged(fullscreenStackVis, dockedStackVis,
2860 mask, fullscreenStackBounds, dockedStackBounds, sbModeChanged, mStatusBarMode);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002861 }
2862
John Spurlockd4e65752013-08-28 14:17:09 -04002863 private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002864 int transientFlag, int translucentFlag, int transparentFlag) {
2865 final int oldMode = barMode(oldVis, transientFlag, translucentFlag, transparentFlag);
2866 final int newMode = barMode(newVis, transientFlag, translucentFlag, transparentFlag);
John Spurlocke1f366f2013-08-05 12:22:40 -04002867 if (oldMode == newMode) {
2868 return -1; // no mode change
2869 }
John Spurlocke1f366f2013-08-05 12:22:40 -04002870 return newMode;
2871 }
2872
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002873 private int barMode(int vis, int transientFlag, int translucentFlag, int transparentFlag) {
2874 int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | transparentFlag;
John Spurlock89835dd2013-08-16 15:06:51 -04002875 return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
John Spurlockbd957402013-10-03 11:38:39 -04002876 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
Adrian Roosc0f0a742014-10-28 16:39:56 +01002877 : (vis & lightsOutTransparent) == lightsOutTransparent ? MODE_LIGHTS_OUT_TRANSPARENT
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002878 : (vis & transparentFlag) != 0 ? MODE_TRANSPARENT
John Spurlock7edfbca2013-09-14 11:58:55 -04002879 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
John Spurlock3b139a92013-08-17 17:18:08 -04002880 : MODE_OPAQUE;
John Spurlocke1f366f2013-08-05 12:22:40 -04002881 }
2882
John Spurlockd4e65752013-08-28 14:17:09 -04002883 private void checkBarModes() {
John Spurlock3c875662013-08-31 15:07:25 -04002884 if (mDemoMode) return;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002885 checkBarMode(mStatusBarMode, mStatusBarWindowState, mStatusBarView.getBarTransitions(),
2886 mNoAnimationOnNextBarModeChange);
John Spurlockd4e65752013-08-28 14:17:09 -04002887 if (mNavigationBarView != null) {
2888 checkBarMode(mNavigationBarMode,
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002889 mNavigationBarWindowState, mNavigationBarView.getBarTransitions(),
2890 mNoAnimationOnNextBarModeChange);
John Spurlockd4e65752013-08-28 14:17:09 -04002891 }
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002892 mNoAnimationOnNextBarModeChange = false;
John Spurlockd4e65752013-08-28 14:17:09 -04002893 }
2894
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002895 private void checkBarMode(int mode, int windowState, BarTransitions transitions,
2896 boolean noAnimation) {
John Spurlock0ff62e02014-07-22 16:15:08 -04002897 final boolean powerSave = mBatteryController.isPowerSave();
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07002898 final boolean anim = !noAnimation && mDeviceInteractive
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002899 && windowState != WINDOW_STATE_HIDDEN && !powerSave;
John Spurlock1bb480a2014-08-02 17:12:43 -04002900 if (powerSave && getBarState() == StatusBarState.SHADE) {
John Spurlock0ff62e02014-07-22 16:15:08 -04002901 mode = MODE_WARNING;
2902 }
John Spurlockc68d5772013-10-08 11:47:58 -04002903 transitions.transitionTo(mode, anim);
John Spurlockd4e65752013-08-28 14:17:09 -04002904 }
2905
John Spurlock42197262013-10-21 09:32:25 -04002906 private void finishBarAnimations() {
2907 mStatusBarView.getBarTransitions().finishAnimations();
2908 if (mNavigationBarView != null) {
2909 mNavigationBarView.getBarTransitions().finishAnimations();
2910 }
2911 }
2912
John Spurlockd4e65752013-08-28 14:17:09 -04002913 private final Runnable mCheckBarModes = new Runnable() {
John Spurlock5b9145b2013-08-20 15:13:47 -04002914 @Override
2915 public void run() {
John Spurlockd4e65752013-08-28 14:17:09 -04002916 checkBarModes();
John Spurlock0ff62e02014-07-22 16:15:08 -04002917 }
2918 };
John Spurlock5b9145b2013-08-20 15:13:47 -04002919
John Spurlockad3e6cb2013-04-30 08:47:43 -04002920 @Override
John Spurlockcfc359a2013-09-05 10:42:03 -04002921 public void setInteracting(int barWindow, boolean interacting) {
John Spurlock7fbf5732014-11-18 11:40:22 -05002922 final boolean changing = ((mInteractingWindows & barWindow) != 0) != interacting;
John Spurlockcfc359a2013-09-05 10:42:03 -04002923 mInteractingWindows = interacting
2924 ? (mInteractingWindows | barWindow)
2925 : (mInteractingWindows & ~barWindow);
2926 if (mInteractingWindows != 0) {
John Spurlockd4e65752013-08-28 14:17:09 -04002927 suspendAutohide();
2928 } else {
2929 resumeSuspendedAutohide();
2930 }
John Spurlock7fbf5732014-11-18 11:40:22 -05002931 // manually dismiss the volume panel when interacting with the nav bar
2932 if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) {
John Spurlockb349af572015-04-29 12:24:19 -04002933 dismissVolumeDialog();
John Spurlock7fbf5732014-11-18 11:40:22 -05002934 }
John Spurlockd4e65752013-08-28 14:17:09 -04002935 checkBarModes();
2936 }
2937
John Spurlockb349af572015-04-29 12:24:19 -04002938 private void dismissVolumeDialog() {
2939 if (mVolumeComponent != null) {
2940 mVolumeComponent.dismissNow();
2941 }
2942 }
2943
John Spurlockd4e65752013-08-28 14:17:09 -04002944 private void resumeSuspendedAutohide() {
John Spurlockad3e6cb2013-04-30 08:47:43 -04002945 if (mAutohideSuspended) {
2946 scheduleAutohide();
John Spurlockd4e65752013-08-28 14:17:09 -04002947 mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher
John Spurlock3b139a92013-08-17 17:18:08 -04002948 }
2949 }
2950
John Spurlockd4e65752013-08-28 14:17:09 -04002951 private void suspendAutohide() {
John Spurlock32beb2c2013-03-11 10:16:47 -04002952 mHandler.removeCallbacks(mAutohide);
John Spurlockd4e65752013-08-28 14:17:09 -04002953 mHandler.removeCallbacks(mCheckBarModes);
John Spurlock5b9145b2013-08-20 15:13:47 -04002954 mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
John Spurlock32beb2c2013-03-11 10:16:47 -04002955 }
2956
2957 private void cancelAutohide() {
2958 mAutohideSuspended = false;
2959 mHandler.removeCallbacks(mAutohide);
2960 }
2961
2962 private void scheduleAutohide() {
2963 cancelAutohide();
2964 mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
2965 }
2966
John Spurlock9deaa282013-07-25 13:03:47 -04002967 private void checkUserAutohide(View v, MotionEvent event) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002968 if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
John Spurlock9deaa282013-07-25 13:03:47 -04002969 && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
2970 && event.getX() == 0 && event.getY() == 0 // a touch outside both bars
2971 ) {
2972 userAutohide();
2973 }
2974 }
2975
2976 private void userAutohide() {
2977 cancelAutohide();
John Spurlock5b9145b2013-08-20 15:13:47 -04002978 mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
John Spurlock9deaa282013-07-25 13:03:47 -04002979 }
2980
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002981 private boolean areLightsOn() {
2982 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
2983 }
Jim Millera073e572012-05-23 17:03:27 -07002984
Daniel Sandler60ee2562011-07-22 12:34:33 -04002985 public void setLightsOn(boolean on) {
2986 Log.v(TAG, "setLightsOn(" + on + ")");
2987 if (on) {
Jorim Jaggi86905582016-02-09 21:36:09 -08002988 setSystemUiVisibility(0, 0, 0, View.SYSTEM_UI_FLAG_LOW_PROFILE,
2989 mLastFullscreenStackBounds, mLastDockedStackBounds);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002990 } else {
Jorim Jaggi86905582016-02-09 21:36:09 -08002991 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, 0, 0,
2992 View.SYSTEM_UI_FLAG_LOW_PROFILE, mLastFullscreenStackBounds,
2993 mLastDockedStackBounds);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002994 }
2995 }
2996
John Spurlock32beb2c2013-03-11 10:16:47 -04002997 private void notifyUiVisibilityChanged(int vis) {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002998 try {
Adrian Roos389beec2015-05-12 13:33:25 -07002999 if (mLastDispatchedSystemUiVisibility != vis) {
3000 mWindowManagerService.statusBarVisibilityChanged(vis);
3001 mLastDispatchedSystemUiVisibility = vis;
3002 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04003003 } catch (RemoteException ex) {
3004 }
Joe Onorato93056472010-09-10 10:30:46 -04003005 }
3006
Daniel Sandler5c8da942011-06-28 00:29:04 -04003007 public void topAppWindowChanged(boolean showMenu) {
Chris Wren8a1638f2016-05-02 16:19:14 -04003008 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04003009 Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
Daniel Sandler5c8da942011-06-28 00:29:04 -04003010 }
3011 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04003012 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04003013 }
3014
3015 // See above re: lights-out policy for legacy apps.
3016 if (showMenu) setLightsOn(true);
3017 }
3018
Daniel Sandler328310c2011-09-23 15:56:52 -04003019 @Override
Jason Monkb605fec2014-05-02 17:04:10 -04003020 public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
3021 boolean showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04003022 boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
3023 int flags = mNavigationIconHints;
3024 if ((backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS) || imeShown) {
3025 flags |= NAVIGATION_HINT_BACK_ALT;
3026 } else {
3027 flags &= ~NAVIGATION_HINT_BACK_ALT;
3028 }
Jason Monkb605fec2014-05-02 17:04:10 -04003029 if (showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04003030 flags |= NAVIGATION_HINT_IME_SHOWN;
3031 } else {
3032 flags &= ~NAVIGATION_HINT_IME_SHOWN;
3033 }
Daniel Sandler328310c2011-09-23 15:56:52 -04003034
Jason Monkf1ff2092014-04-29 16:50:53 -04003035 setNavigationIconHints(flags);
Daniel Sandler328310c2011-09-23 15:56:52 -04003036 }
3037
Daniel Sandler48852952011-12-01 14:34:23 -05003038 public static String viewInfo(View v) {
3039 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
3040 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04003041 }
3042
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04003043 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04003044 synchronized (mQueueLock) {
3045 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04003046 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04003047 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04003048 pw.println(" mTracking=" + mTracking);
Daniel Sandler36412a72011-08-04 09:35:13 -04003049 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Selim Cinekb6d85eb2014-03-28 20:21:01 +01003050 pw.println(" mStackScroller: " + viewInfo(mStackScroller));
Selim Cinekb6d85eb2014-03-28 20:21:01 +01003051 pw.println(" mStackScroller: " + viewInfo(mStackScroller)
3052 + " scroll " + mStackScroller.getScrollX()
3053 + "," + mStackScroller.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04003054 }
Joe Onorato808182d2010-07-09 18:52:06 -04003055
John Spurlockcfc359a2013-09-05 10:42:03 -04003056 pw.print(" mInteractingWindows="); pw.println(mInteractingWindows);
John Spurlock0ec64c62013-08-26 15:37:58 -04003057 pw.print(" mStatusBarWindowState=");
3058 pw.println(windowStateToString(mStatusBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04003059 pw.print(" mStatusBarMode=");
3060 pw.println(BarTransitions.modeToString(mStatusBarMode));
John Spurlockbf370992014-06-17 13:58:31 -04003061 pw.print(" mDozing="); pw.println(mDozing);
John Spurlocke677d712014-02-13 12:52:19 -05003062 pw.print(" mZenMode=");
3063 pw.println(Settings.Global.zenModeToString(mZenMode));
Chris Wren3b6745b2014-03-07 14:34:35 -05003064 pw.print(" mUseHeadsUp=");
3065 pw.println(mUseHeadsUp);
John Spurlock0ec64c62013-08-26 15:37:58 -04003066 dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
3067 if (mNavigationBarView != null) {
3068 pw.print(" mNavigationBarWindowState=");
3069 pw.println(windowStateToString(mNavigationBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04003070 pw.print(" mNavigationBarMode=");
3071 pw.println(BarTransitions.modeToString(mNavigationBarMode));
John Spurlock0ec64c62013-08-26 15:37:58 -04003072 dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
3073 }
3074
Daniel Sandler48852952011-12-01 14:34:23 -05003075 pw.print(" mNavigationBarView=");
3076 if (mNavigationBarView == null) {
3077 pw.println("null");
3078 } else {
3079 mNavigationBarView.dump(fd, pw, args);
3080 }
3081
Dan Sandler16128f42014-05-21 12:48:22 -04003082 pw.print(" mMediaSessionManager=");
3083 pw.println(mMediaSessionManager);
3084 pw.print(" mMediaNotificationKey=");
3085 pw.println(mMediaNotificationKey);
3086 pw.print(" mMediaController=");
3087 pw.print(mMediaController);
3088 if (mMediaController != null) {
3089 pw.print(" state=" + mMediaController.getPlaybackState());
3090 }
3091 pw.println();
3092 pw.print(" mMediaMetadata=");
3093 pw.print(mMediaMetadata);
3094 if (mMediaMetadata != null) {
RoboErik75847b92014-07-29 13:10:17 -07003095 pw.print(" title=" + mMediaMetadata.getText(MediaMetadata.METADATA_KEY_TITLE));
Dan Sandler16128f42014-05-21 12:48:22 -04003096 }
3097 pw.println();
3098
Daniel Sandler37a38aa2013-02-13 17:15:57 -05003099 pw.println(" Panels: ");
3100 if (mNotificationPanel != null) {
3101 pw.println(" mNotificationPanel=" +
3102 mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""));
3103 pw.print (" ");
3104 mNotificationPanel.dump(fd, pw, args);
3105 }
Daniel Sandler37a38aa2013-02-13 17:15:57 -05003106
John Spurlock813552c2014-09-19 08:30:21 -04003107 DozeLog.dump(pw);
3108
Daniel Sandler7579bca2011-08-18 15:47:26 -04003109 if (DUMPTRUCK) {
3110 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02003111 mNotificationData.dump(pw, " ");
Daniel Sandler7579bca2011-08-18 15:47:26 -04003112 }
3113
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003114 mIconController.dump(pw);
Jim Miller5e6af442011-12-02 18:24:26 -08003115
Daniel Sandler89d97132011-09-08 15:31:57 -04003116 if (false) {
3117 pw.println("see the logcat for a dump of the views we have created.");
3118 // must happen on ui thread
3119 mHandler.post(new Runnable() {
3120 public void run() {
3121 mStatusBarView.getLocationOnScreen(mAbsPos);
John Spurlockcd686b52013-06-05 10:13:46 -04003122 Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
Daniel Sandler89d97132011-09-08 15:31:57 -04003123 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04003124 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04003125 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04003126 }
3127 });
3128 }
Joe Onorato808182d2010-07-09 18:52:06 -04003129 }
Daniel Sandler89d97132011-09-08 15:31:57 -04003130
Daniel Sandler151f00d2012-10-02 22:33:08 -04003131 if (DEBUG_GESTURES) {
3132 pw.print(" status bar gestures: ");
3133 mGestureRec.dump(fd, pw, args);
3134 }
Selim Cinek7025f262015-07-13 16:22:48 -07003135 if (mStatusBarWindowManager != null) {
3136 mStatusBarWindowManager.dump(fd, pw, args);
3137 }
John Spurlock486b78e2014-07-07 08:37:56 -04003138 if (mNetworkController != null) {
3139 mNetworkController.dump(fd, pw, args);
3140 }
3141 if (mBluetoothController != null) {
3142 mBluetoothController.dump(fd, pw, args);
3143 }
Jason Monkdd5bdc62015-07-20 12:18:38 -04003144 if (mHotspotController != null) {
3145 mHotspotController.dump(fd, pw, args);
3146 }
John Spurlock1e6eb172014-07-13 11:59:50 -04003147 if (mCastController != null) {
3148 mCastController.dump(fd, pw, args);
3149 }
Adrian Roos00a0b1f2014-07-16 16:44:49 +02003150 if (mUserSwitcherController != null) {
3151 mUserSwitcherController.dump(fd, pw, args);
3152 }
John Spurlock0ff62e02014-07-22 16:15:08 -04003153 if (mBatteryController != null) {
3154 mBatteryController.dump(fd, pw, args);
3155 }
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02003156 if (mNextAlarmController != null) {
3157 mNextAlarmController.dump(fd, pw, args);
3158 }
Jason Monk3d5f5512014-07-25 11:17:28 -04003159 if (mSecurityController != null) {
3160 mSecurityController.dump(fd, pw, args);
3161 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07003162 if (mHeadsUpManager != null) {
3163 mHeadsUpManager.dump(fd, pw, args);
Chris Wren428c6b62014-12-05 16:07:06 -05003164 } else {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07003165 pw.println(" mHeadsUpManager: null");
Chris Wren428c6b62014-12-05 16:07:06 -05003166 }
Selim Cinek52941c52016-05-07 18:29:32 -04003167 if (mGroupManager != null) {
3168 mGroupManager.dump(fd, pw, args);
3169 } else {
3170 pw.println(" mGroupManager: null");
3171 }
Jason Monkab525272015-07-13 17:02:49 -04003172 if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
3173 KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
3174 }
Chris Wren428c6b62014-12-05 16:07:06 -05003175
Adrian Roos401caae2016-03-04 13:35:21 -08003176 FalsingManager.getInstance(mContext).dump(pw);
3177 FalsingLog.dump(pw);
3178
John Spurlock7bbb9f62014-10-21 12:15:28 -04003179 pw.println("SharedPreferences:");
Andrew Flynn82862572015-04-01 14:22:37 -04003180 for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
John Spurlock7bbb9f62014-10-21 12:15:28 -04003181 pw.print(" "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
3182 }
Joe Onorato808182d2010-07-09 18:52:06 -04003183 }
3184
John Spurlock0ec64c62013-08-26 15:37:58 -04003185 private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
3186 pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
3187 pw.println(BarTransitions.modeToString(transitions.getMode()));
3188 }
3189
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05003190 @Override
3191 public void createAndAddWindows() {
3192 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04003193 }
Jim Millere898ac52012-04-06 17:10:57 -07003194
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05003195 private void addStatusBarWindow() {
Daniel Sandlera310af82012-04-24 01:20:13 -04003196 makeStatusBarView();
Jorim Jaggi5cf17872014-03-26 18:31:48 +01003197 mStatusBarWindowManager = new StatusBarWindowManager(mContext);
Adrian Roos1c0ca502015-10-07 12:20:42 -07003198 mRemoteInputController = new RemoteInputController(mStatusBarWindowManager,
3199 mHeadsUpManager);
Jorim Jaggi5cf17872014-03-26 18:31:48 +01003200 mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
Joe Onorato808182d2010-07-09 18:52:06 -04003201 }
3202
Daniel Sandler747a9e92012-08-10 16:39:19 -04003203 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07003204 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04003205 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler7e8ae502013-10-10 23:38:19 -04003206 mDisplay.getSize(mCurrentDisplaySize);
Daniel Sandler151f00d2012-10-02 22:33:08 -04003207 if (DEBUG_GESTURES) {
John Spurlock209bede2013-07-17 12:23:27 -04003208 mGestureRec.tag("display",
Daniel Sandler151f00d2012-10-02 22:33:08 -04003209 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
3210 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07003211 }
3212
Christoph Studerb0183992014-12-22 21:02:26 +01003213 float getDisplayDensity() {
3214 return mDisplayMetrics.density;
3215 }
3216
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003217 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
Jorim Jaggid9449862015-05-29 14:49:08 -07003218 boolean dismissShade) {
3219 startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, null /* callback */);
3220 }
3221
3222 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
3223 final boolean dismissShade, final Callback callback) {
Daniel Sandler3679bf52012-10-16 21:30:28 -04003224 if (onlyProvisioned && !isDeviceProvisioned()) return;
Adrian Roos4314f6d2014-05-28 14:10:27 +02003225
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02003226 final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
3227 mContext, intent, mCurrentUserId);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02003228 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Selim Cineke70d6532015-04-24 16:46:13 -07003229 Runnable runnable = new Runnable() {
3230 public void run() {
Jorim Jaggib835dd72015-06-08 12:28:42 -07003231 mAssistManager.hideAssist();
Selim Cineke70d6532015-04-24 16:46:13 -07003232 intent.setFlags(
3233 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Jorim Jaggid9449862015-05-29 14:49:08 -07003234 int result = ActivityManager.START_CANCELED;
3235 try {
3236 result = ActivityManagerNative.getDefault().startActivityAsUser(
3237 null, mContext.getBasePackageName(),
3238 intent,
3239 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Jorim Jaggie6e108e2016-03-28 13:38:45 -07003240 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
3241 getActivityOptions(), UserHandle.CURRENT.getIdentifier());
Jorim Jaggid9449862015-05-29 14:49:08 -07003242 } catch (RemoteException e) {
3243 Log.w(TAG, "Unable to start activity", e);
3244 }
Selim Cineke70d6532015-04-24 16:46:13 -07003245 overrideActivityPendingAppTransition(
3246 keyguardShowing && !afterKeyguardGone);
Jorim Jaggid9449862015-05-29 14:49:08 -07003247 if (callback != null) {
3248 callback.onActivityStarted(result);
3249 }
Selim Cineke70d6532015-04-24 16:46:13 -07003250 }
3251 };
Jorim Jaggid9449862015-05-29 14:49:08 -07003252 Runnable cancelRunnable = new Runnable() {
3253 @Override
3254 public void run() {
Jorim Jaggi5cc86592015-06-08 14:48:28 -07003255 if (callback != null) {
3256 callback.onActivityStarted(ActivityManager.START_CANCELED);
3257 }
Jorim Jaggid9449862015-05-29 14:49:08 -07003258 }
3259 };
Jorim Jaggib835dd72015-06-08 12:28:42 -07003260 executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShade,
Felipe Lemeee5d6302016-04-22 16:11:19 -07003261 afterKeyguardGone, true /* deferred */);
Selim Cineke70d6532015-04-24 16:46:13 -07003262 }
3263
3264 public void executeRunnableDismissingKeyguard(final Runnable runnable,
Jorim Jaggid9449862015-05-29 14:49:08 -07003265 final Runnable cancelAction,
Selim Cineke70d6532015-04-24 16:46:13 -07003266 final boolean dismissShade,
Felipe Lemeee5d6302016-04-22 16:11:19 -07003267 final boolean afterKeyguardGone,
3268 final boolean deferred) {
Selim Cineke70d6532015-04-24 16:46:13 -07003269 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Adrian Roos4314f6d2014-05-28 14:10:27 +02003270 dismissKeyguardThenExecute(new OnDismissAction() {
3271 @Override
3272 public boolean onDismiss() {
Selim Cinekbaa23272014-07-08 18:01:07 +02003273 AsyncTask.execute(new Runnable() {
3274 public void run() {
3275 try {
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02003276 if (keyguardShowing && !afterKeyguardGone) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003277 ActivityManagerNative.getDefault()
3278 .keyguardWaitingForActivityDrawn();
3279 }
Selim Cineke70d6532015-04-24 16:46:13 -07003280 if (runnable != null) {
3281 runnable.run();
3282 }
Selim Cinekbaa23272014-07-08 18:01:07 +02003283 } catch (RemoteException e) {
3284 }
3285 }
3286 });
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003287 if (dismissShade) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -07003288 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
3289 true /* delayed*/);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003290 }
Felipe Lemeee5d6302016-04-22 16:11:19 -07003291 return deferred;
Adrian Roos4314f6d2014-05-28 14:10:27 +02003292 }
Jorim Jaggid9449862015-05-29 14:49:08 -07003293 }, cancelAction, afterKeyguardGone);
Daniel Sandler3679bf52012-10-16 21:30:28 -04003294 }
3295
Joe Onorato808182d2010-07-09 18:52:06 -04003296 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
3297 public void onReceive(Context context, Intent intent) {
John Spurlockcd686b52013-06-05 10:13:46 -04003298 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04003299 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04003300 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Andrei Stingaceanuf86bc972016-04-12 15:29:25 +01003301 KeyboardShortcuts.dismiss();
Kenny Guy44fc65f2014-11-28 22:18:14 +00003302 if (isCurrentProfile(getSendingUserId())) {
3303 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
3304 String reason = intent.getStringExtra("reason");
3305 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
3306 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
3307 }
3308 animateCollapsePanels(flags);
Michael Jurka3b1fc472011-06-13 10:54:40 -07003309 }
Joe Onorato808182d2010-07-09 18:52:06 -04003310 }
Daniel Sandlered930e52012-07-03 14:31:22 -04003311 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
John Spurlock1bbd49d2012-10-19 11:09:32 -04003312 notifyNavigationBarScreenOn(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07003313 notifyHeadsUpScreenOff();
John Spurlock42197262013-10-21 09:32:25 -04003314 finishBarAnimations();
Selim Cinekccd14fb2014-08-12 18:53:24 +02003315 resetUserExpandedStates();
Daniel Sandlered930e52012-07-03 14:31:22 -04003316 }
Daniel Sandler7f3cf952012-08-31 14:57:09 -04003317 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
John Spurlock1bbd49d2012-10-19 11:09:32 -04003318 notifyNavigationBarScreenOn(true);
Joe Onorato808182d2010-07-09 18:52:06 -04003319 }
Adrian Roos8e3e8362015-07-16 19:42:22 -07003320 }
3321 };
3322
3323 private BroadcastReceiver mDemoReceiver = new BroadcastReceiver() {
3324 public void onReceive(Context context, Intent intent) {
3325 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
3326 String action = intent.getAction();
3327 if (ACTION_DEMO.equals(action)) {
John Spurlock3c875662013-08-31 15:07:25 -04003328 Bundle bundle = intent.getExtras();
3329 if (bundle != null) {
3330 String command = bundle.getString("command", "").trim().toLowerCase();
3331 if (command.length() > 0) {
3332 try {
3333 dispatchDemoCommand(command, bundle);
3334 } catch (Throwable t) {
3335 Log.w(TAG, "Error running demo command, intent=" + intent, t);
3336 }
3337 }
3338 }
Adrian Roos8e3e8362015-07-16 19:42:22 -07003339 } else if (ACTION_FAKE_ARTWORK.equals(action)) {
Dan Sandler16128f42014-05-21 12:48:22 -04003340 if (DEBUG_MEDIA_FAKE_ARTWORK) {
Adrian Roos52738322016-01-29 08:49:21 -08003341 updateMediaMetaData(true, true);
Dan Sandler16128f42014-05-21 12:48:22 -04003342 }
John Spurlock3c875662013-08-31 15:07:25 -04003343 }
Joe Onorato808182d2010-07-09 18:52:06 -04003344 }
3345 };
3346
Selim Cinek78f40082016-03-10 18:06:27 -08003347 public void resetUserExpandedStates() {
Selim Cinekccd14fb2014-08-12 18:53:24 +02003348 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
3349 final int notificationCount = activeNotifications.size();
3350 for (int i = 0; i < notificationCount; i++) {
3351 NotificationData.Entry entry = activeNotifications.get(i);
3352 if (entry.row != null) {
3353 entry.row.resetUserExpansion();
3354 }
3355 }
3356 }
3357
Adrian Roos7d7090d2014-05-21 13:10:23 +02003358 @Override
Jorim Jaggid9449862015-05-29 14:49:08 -07003359 protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
3360 dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
3361 }
3362
Jason Monkabe19742015-09-29 09:47:06 -04003363 public void dismissKeyguard() {
3364 mStatusBarKeyguardViewManager.dismiss();
3365 }
3366
Jorim Jaggid9449862015-05-29 14:49:08 -07003367 private void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02003368 boolean afterKeyguardGone) {
Adrian Roos7d7090d2014-05-21 13:10:23 +02003369 if (mStatusBarKeyguardViewManager.isShowing()) {
Jorim Jaggid9449862015-05-29 14:49:08 -07003370 mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
3371 afterKeyguardGone);
Adrian Roos7d7090d2014-05-21 13:10:23 +02003372 } else {
3373 action.onDismiss();
3374 }
3375 }
3376
Daniel Sandler777dcde2013-09-30 10:21:45 -04003377 // SystemUIService notifies SystemBars of configuration changes, which then calls down here
3378 @Override
3379 protected void onConfigurationChanged(Configuration newConfig) {
Selim Cinek3e7592d2016-04-11 09:35:54 +08003380 updateResources();
3381 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler777dcde2013-09-30 10:21:45 -04003382 super.onConfigurationChanged(newConfig); // calls refreshLayout
3383
3384 if (DEBUG) {
3385 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
3386 }
Daniel Sandler777dcde2013-09-30 10:21:45 -04003387
Daniel Sandler777dcde2013-09-30 10:21:45 -04003388 repositionNavigationBar();
Jorim Jaggif6411742014-08-05 17:10:43 +00003389 updateRowStates();
Selim Cinek3e7592d2016-04-11 09:35:54 +08003390 mIconController.defineSlots();
Jason Monk18f99d92014-09-11 13:36:42 -04003391 mScreenPinningRequest.onConfigurationChanged();
Jason Monk1c040db2015-07-20 09:45:54 -04003392 mNetworkController.onConfigurationChanged();
Daniel Sandler777dcde2013-09-30 10:21:45 -04003393 }
3394
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003395 @Override
3396 public void userSwitched(int newUserId) {
Chris Wrena6d4fb62014-11-20 14:46:23 -05003397 super.userSwitched(newUserId);
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003398 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04003399 animateCollapsePanels();
Adrian Roos31b844b2014-11-21 13:55:09 +01003400 updatePublicMode();
Christoph Studer37fe6932014-05-26 13:10:30 +02003401 updateNotifications();
John Spurlock919adac2012-10-02 16:41:12 -04003402 resetUserSetupObserver();
John Spurlock89f060a2014-07-16 21:03:15 -04003403 setControllerUsers();
Julia Reynolds86ef8e22015-09-09 16:42:38 -04003404 clearCurrentMediaNotification();
Vadim Tryshev12a30e82016-02-12 15:39:28 -08003405 mLockscreenWallpaper.setCurrentUser(newUserId);
Adrian Roos52738322016-01-29 08:49:21 -08003406 updateMediaMetaData(true, false);
John Spurlock89f060a2014-07-16 21:03:15 -04003407 }
3408
3409 private void setControllerUsers() {
3410 if (mZenModeController != null) {
3411 mZenModeController.setUserId(mCurrentUserId);
3412 }
Robin Lee63204ee2015-06-04 01:53:01 +01003413 if (mSecurityController != null) {
3414 mSecurityController.onUserSwitched(mCurrentUserId);
3415 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003416 }
John Spurlock919adac2012-10-02 16:41:12 -04003417
3418 private void resetUserSetupObserver() {
3419 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
3420 mUserSetupObserver.onChange(false);
3421 mContext.getContentResolver().registerContentObserver(
3422 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003423 mUserSetupObserver, mCurrentUserId);
John Spurlock919adac2012-10-02 16:41:12 -04003424 }
3425
Joe Onorato808182d2010-07-09 18:52:06 -04003426 /**
3427 * Reload some of our resources when the configuration changes.
3428 *
3429 * We don't reload everything when the configuration changes -- we probably
3430 * should, but getting that smooth is tough. Someday we'll fix that. In the
3431 * meantime, just update the things that we know change.
3432 */
3433 void updateResources() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04003434 // Update the quick setting tiles
John Spurlock7e6809a2014-08-06 16:03:14 -04003435 if (mQSPanel != null) {
3436 mQSPanel.updateResources();
3437 }
Winson Chungd63c59782012-09-05 17:34:41 -07003438
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003439 loadDimens();
John Spurlock7e6809a2014-08-06 16:03:14 -04003440
3441 if (mNotificationPanel != null) {
3442 mNotificationPanel.updateResources();
3443 }
Adrian Roos5fd872e2014-08-12 17:28:58 +02003444 if (mBrightnessMirrorController != null) {
3445 mBrightnessMirrorController.updateResources();
3446 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003447 }
Jim Miller5e6af442011-12-02 18:24:26 -08003448
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003449 protected void loadDimens() {
3450 final Resources res = mContext.getResources();
3451
Jorim Jaggi11c62e12016-04-05 20:41:21 -07003452 int oldBarHeight = mNaturalBarHeight;
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003453 mNaturalBarHeight = res.getDimensionPixelSize(
3454 com.android.internal.R.dimen.status_bar_height);
Jorim Jaggi11c62e12016-04-05 20:41:21 -07003455 if (mStatusBarWindowManager != null && mNaturalBarHeight != oldBarHeight) {
3456 mStatusBarWindowManager.setBarHeight(mNaturalBarHeight);
3457 }
3458 mMaxAllowedKeyguardNotifications = res.getInteger(
3459 R.integer.keyguard_max_notification_count);
Jorim Jaggid4a57442014-04-10 02:45:55 +02003460
Selim Cinek3e7592d2016-04-11 09:35:54 +08003461 if (DEBUG) Log.v(TAG, "defineSlots");
John Spurlock804df702012-06-01 15:34:27 -04003462 }
3463
Christoph Studer92b389d2014-04-01 18:44:40 +02003464 // Visibility reporting
3465
3466 @Override
Christoph Studere8e28652014-10-29 17:27:53 +01003467 protected void handleVisibleToUserChanged(boolean visibleToUser) {
3468 if (visibleToUser) {
3469 super.handleVisibleToUserChanged(visibleToUser);
3470 startNotificationLogging();
Christoph Studer92b389d2014-04-01 18:44:40 +02003471 } else {
Christoph Studer037e34c2014-04-30 20:06:04 +02003472 stopNotificationLogging();
Christoph Studere8e28652014-10-29 17:27:53 +01003473 super.handleVisibleToUserChanged(visibleToUser);
Christoph Studer92b389d2014-04-01 18:44:40 +02003474 }
Christoph Studer92b389d2014-04-01 18:44:40 +02003475 }
3476
Christoph Studer037e34c2014-04-30 20:06:04 +02003477 private void stopNotificationLogging() {
3478 // Report all notifications as invisible and turn down the
3479 // reporter.
3480 if (!mCurrentlyVisibleNotifications.isEmpty()) {
Chris Wrend1dbc922015-06-19 17:51:16 -04003481 logNotificationVisibilityChanges(Collections.<NotificationVisibility>emptyList(),
3482 mCurrentlyVisibleNotifications);
3483 recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
Christoph Studer037e34c2014-04-30 20:06:04 +02003484 }
3485 mHandler.removeCallbacks(mVisibilityReporter);
3486 mStackScroller.setChildLocationsChangedListener(null);
3487 }
3488
Christoph Studere8e28652014-10-29 17:27:53 +01003489 private void startNotificationLogging() {
3490 mStackScroller.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
3491 // Some transitions like mVisibleToUser=false -> mVisibleToUser=true don't
3492 // cause the scroller to emit child location events. Hence generate
3493 // one ourselves to guarantee that we're reporting visible
3494 // notifications.
3495 // (Note that in cases where the scroller does emit events, this
3496 // additional event doesn't break anything.)
3497 mNotificationLocationsChangedListener.onChildLocationsChanged(mStackScroller);
Christoph Studer037e34c2014-04-30 20:06:04 +02003498 }
3499
Christoph Studer92b389d2014-04-01 18:44:40 +02003500 private void logNotificationVisibilityChanges(
Chris Wrend1dbc922015-06-19 17:51:16 -04003501 Collection<NotificationVisibility> newlyVisible,
3502 Collection<NotificationVisibility> noLongerVisible) {
Christoph Studer92b389d2014-04-01 18:44:40 +02003503 if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
3504 return;
3505 }
Chris Wrend1dbc922015-06-19 17:51:16 -04003506 NotificationVisibility[] newlyVisibleAr =
3507 newlyVisible.toArray(new NotificationVisibility[newlyVisible.size()]);
3508 NotificationVisibility[] noLongerVisibleAr =
3509 noLongerVisible.toArray(new NotificationVisibility[noLongerVisible.size()]);
Christoph Studer92b389d2014-04-01 18:44:40 +02003510 try {
3511 mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr);
3512 } catch (RemoteException e) {
3513 // Ignore.
3514 }
Chris Wrend1dbc922015-06-19 17:51:16 -04003515
3516 final int N = newlyVisible.size();
Amith Yamasani76495672015-07-07 15:22:54 -07003517 if (N > 0) {
3518 String[] newlyVisibleKeyAr = new String[N];
3519 for (int i = 0; i < N; i++) {
3520 newlyVisibleKeyAr[i] = newlyVisibleAr[i].key;
3521 }
3522
3523 setNotificationsShown(newlyVisibleKeyAr);
Chris Wrend1dbc922015-06-19 17:51:16 -04003524 }
Christoph Studer92b389d2014-04-01 18:44:40 +02003525 }
3526
Christoph Studer2231c6e2014-12-19 12:40:13 +01003527 // State logging
3528
3529 private void logStateToEventlog() {
3530 boolean isShowing = mStatusBarKeyguardViewManager.isShowing();
3531 boolean isOccluded = mStatusBarKeyguardViewManager.isOccluded();
3532 boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing();
3533 boolean isSecure = mUnlockMethodCache.isMethodSecure();
Selim Cineke8bae622015-07-15 13:24:06 -07003534 boolean canSkipBouncer = mUnlockMethodCache.canSkipBouncer();
Christoph Studer2231c6e2014-12-19 12:40:13 +01003535 int stateFingerprint = getLoggingFingerprint(mState,
3536 isShowing,
3537 isOccluded,
3538 isBouncerShowing,
3539 isSecure,
Selim Cineke8bae622015-07-15 13:24:06 -07003540 canSkipBouncer);
Christoph Studer2231c6e2014-12-19 12:40:13 +01003541 if (stateFingerprint != mLastLoggedStateFingerprint) {
3542 EventLogTags.writeSysuiStatusBarState(mState,
3543 isShowing ? 1 : 0,
3544 isOccluded ? 1 : 0,
3545 isBouncerShowing ? 1 : 0,
3546 isSecure ? 1 : 0,
Selim Cineke8bae622015-07-15 13:24:06 -07003547 canSkipBouncer ? 1 : 0);
Christoph Studer2231c6e2014-12-19 12:40:13 +01003548 mLastLoggedStateFingerprint = stateFingerprint;
3549 }
3550 }
3551
3552 /**
3553 * Returns a fingerprint of fields logged to eventlog
3554 */
3555 private static int getLoggingFingerprint(int statusBarState, boolean keyguardShowing,
3556 boolean keyguardOccluded, boolean bouncerShowing, boolean secure,
3557 boolean currentlyInsecure) {
3558 // Reserve 8 bits for statusBarState. We'll never go higher than
3559 // that, right? Riiiight.
3560 return (statusBarState & 0xFF)
3561 | ((keyguardShowing ? 1 : 0) << 8)
3562 | ((keyguardOccluded ? 1 : 0) << 9)
3563 | ((bouncerShowing ? 1 : 0) << 10)
3564 | ((secure ? 1 : 0) << 11)
3565 | ((currentlyInsecure ? 1 : 0) << 12);
3566 }
3567
Joe Onorato808182d2010-07-09 18:52:06 -04003568 //
3569 // tracing
3570 //
3571
3572 void postStartTracing() {
3573 mHandler.postDelayed(mStartTracing, 3000);
3574 }
3575
3576 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04003577 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
3578 Context.VIBRATOR_SERVICE);
John Spurlock7b414672014-07-18 13:02:39 -04003579 vib.vibrate(250, VIBRATION_ATTRIBUTES);
Joe Onorato808182d2010-07-09 18:52:06 -04003580 }
3581
3582 Runnable mStartTracing = new Runnable() {
3583 public void run() {
3584 vibrate();
3585 SystemClock.sleep(250);
John Spurlockcd686b52013-06-05 10:13:46 -04003586 Log.d(TAG, "startTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04003587 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
3588 mHandler.postDelayed(mStopTracing, 10000);
3589 }
3590 };
3591
3592 Runnable mStopTracing = new Runnable() {
3593 public void run() {
3594 android.os.Debug.stopMethodTracing();
John Spurlockcd686b52013-06-05 10:13:46 -04003595 Log.d(TAG, "stopTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04003596 vibrate();
3597 }
3598 };
Chris Wren0c8275b2012-05-08 13:36:48 -04003599
3600 @Override
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07003601 public boolean shouldDisableNavbarGestures() {
Jorim Jaggi18976a52015-07-24 13:18:19 -07003602 return !isDeviceProvisioned() || (mDisabled1 & StatusBarManager.DISABLE_SEARCH) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07003603 }
Joe Onorato808182d2010-07-09 18:52:06 -04003604
Jason Monkba2318e2015-12-08 09:04:23 -05003605 public void postQSRunnableDismissingKeyguard(final Runnable runnable) {
3606 mHandler.post(new Runnable() {
3607 @Override
3608 public void run() {
3609 mLeaveOpenOnKeyguardHide = true;
Felipe Lemeee5d6302016-04-22 16:11:19 -07003610 executeRunnableDismissingKeyguard(runnable, null, false, false, false);
Jason Monkba2318e2015-12-08 09:04:23 -05003611 }
3612 });
3613 }
3614
Adrian Roos62692b22015-09-11 17:46:23 -07003615 public void postStartActivityDismissingKeyguard(final PendingIntent intent) {
3616 mHandler.post(new Runnable() {
3617 @Override
3618 public void run() {
3619 startPendingIntentDismissingKeyguard(intent);
3620 }
3621 });
3622 }
3623
Jason Monkee43cdf2015-06-19 14:20:46 -04003624 public void postStartActivityDismissingKeyguard(final Intent intent, int delay) {
John Spurlockd47a3f32014-05-18 19:14:14 -04003625 mHandler.postDelayed(new Runnable() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04003626 @Override
3627 public void run() {
Jason Monkee43cdf2015-06-19 14:20:46 -04003628 handleStartActivityDismissingKeyguard(intent, true /*onlyProvisioned*/);
John Spurlockaf8d6c42014-05-07 17:49:08 -04003629 }
John Spurlockd47a3f32014-05-18 19:14:14 -04003630 }, delay);
John Spurlockaf8d6c42014-05-07 17:49:08 -04003631 }
3632
Jason Monkee43cdf2015-06-19 14:20:46 -04003633 private void handleStartActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) {
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02003634 startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
John Spurlockde547002014-02-28 17:50:39 -05003635 }
3636
Romain Guy648342f2012-05-25 10:44:45 -07003637 private static class FastColorDrawable extends Drawable {
3638 private final int mColor;
3639
3640 public FastColorDrawable(int color) {
3641 mColor = 0xff000000 | color;
3642 }
3643
3644 @Override
3645 public void draw(Canvas canvas) {
3646 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
3647 }
3648
3649 @Override
3650 public void setAlpha(int alpha) {
3651 }
3652
3653 @Override
Chris Craikbd3bfc52015-03-02 10:43:29 -08003654 public void setColorFilter(ColorFilter colorFilter) {
Romain Guy648342f2012-05-25 10:44:45 -07003655 }
3656
3657 @Override
3658 public int getOpacity() {
3659 return PixelFormat.OPAQUE;
3660 }
3661
3662 @Override
3663 public void setBounds(int left, int top, int right, int bottom) {
3664 }
3665
3666 @Override
3667 public void setBounds(Rect bounds) {
3668 }
3669 }
John Spurlock5c454122013-06-17 07:35:46 -04003670
3671 @Override
3672 public void destroy() {
3673 super.destroy();
3674 if (mStatusBarWindow != null) {
3675 mWindowManager.removeViewImmediate(mStatusBarWindow);
John Spurlockab847cf2014-01-15 14:13:59 -05003676 mStatusBarWindow = null;
John Spurlock5c454122013-06-17 07:35:46 -04003677 }
3678 if (mNavigationBarView != null) {
3679 mWindowManager.removeViewImmediate(mNavigationBarView);
John Spurlockab847cf2014-01-15 14:13:59 -05003680 mNavigationBarView = null;
John Spurlock5c454122013-06-17 07:35:46 -04003681 }
Jason Monk4ae97d32014-12-17 10:14:33 -05003682 if (mHandlerThread != null) {
3683 mHandlerThread.quitSafely();
3684 mHandlerThread = null;
3685 }
John Spurlock5c454122013-06-17 07:35:46 -04003686 mContext.unregisterReceiver(mBroadcastReceiver);
Adrian Roos8e3e8362015-07-16 19:42:22 -07003687 mContext.unregisterReceiver(mDemoReceiver);
Selim Cineke70d6532015-04-24 16:46:13 -07003688 mAssistManager.destroy();
Jason Monk07b75fe2015-05-14 16:47:03 -04003689
3690 final SignalClusterView signalCluster =
3691 (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
3692 final SignalClusterView signalClusterKeyguard =
3693 (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
3694 final SignalClusterView signalClusterQs =
3695 (SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
Jason Monk5e745172015-06-02 19:14:44 -04003696 mNetworkController.removeSignalCallback(signalCluster);
3697 mNetworkController.removeSignalCallback(signalClusterKeyguard);
3698 mNetworkController.removeSignalCallback(signalClusterQs);
3699 if (mQSPanel != null && mQSPanel.getHost() != null) {
3700 mQSPanel.getHost().destroy();
3701 }
John Spurlock5c454122013-06-17 07:35:46 -04003702 }
John Spurlock3c875662013-08-31 15:07:25 -04003703
3704 private boolean mDemoModeAllowed;
3705 private boolean mDemoMode;
John Spurlock3c875662013-08-31 15:07:25 -04003706
3707 @Override
3708 public void dispatchDemoCommand(String command, Bundle args) {
3709 if (!mDemoModeAllowed) {
3710 mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
Jason Monk431ad732015-07-16 08:58:15 -04003711 DEMO_MODE_ALLOWED, 0) != 0;
John Spurlock3c875662013-08-31 15:07:25 -04003712 }
3713 if (!mDemoModeAllowed) return;
3714 if (command.equals(COMMAND_ENTER)) {
3715 mDemoMode = true;
3716 } else if (command.equals(COMMAND_EXIT)) {
3717 mDemoMode = false;
3718 checkBarModes();
3719 } else if (!mDemoMode) {
3720 // automatically enter demo mode on first demo command
3721 dispatchDemoCommand(COMMAND_ENTER, new Bundle());
3722 }
3723 boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
John Spurlockbb4a7022014-11-08 12:40:19 -05003724 if ((modeChange || command.equals(COMMAND_VOLUME)) && mVolumeComponent != null) {
3725 mVolumeComponent.dispatchDemoCommand(command, args);
3726 }
John Spurlock3c875662013-08-31 15:07:25 -04003727 if (modeChange || command.equals(COMMAND_CLOCK)) {
3728 dispatchDemoCommandToView(command, args, R.id.clock);
3729 }
3730 if (modeChange || command.equals(COMMAND_BATTERY)) {
Jason Monk98d7c7a2016-04-12 13:08:31 -04003731 mBatteryController.dispatchDemoCommand(command, args);
John Spurlock3c875662013-08-31 15:07:25 -04003732 }
3733 if (modeChange || command.equals(COMMAND_STATUS)) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003734 mIconController.dispatchDemoCommand(command, args);
John Spurlock3c875662013-08-31 15:07:25 -04003735 }
3736 if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
3737 mNetworkController.dispatchDemoCommand(command, args);
3738 }
John Spurlock7f42fc52014-01-14 16:20:39 -05003739 if (modeChange || command.equals(COMMAND_NOTIFICATIONS)) {
3740 View notifications = mStatusBarView == null ? null
3741 : mStatusBarView.findViewById(R.id.notification_icon_area);
3742 if (notifications != null) {
3743 String visible = args.getString("visible");
3744 int vis = mDemoMode && "false".equals(visible) ? View.INVISIBLE : View.VISIBLE;
3745 notifications.setVisibility(vis);
3746 }
3747 }
John Spurlock3c875662013-08-31 15:07:25 -04003748 if (command.equals(COMMAND_BARS)) {
3749 String mode = args.getString("mode");
3750 int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
John Spurlockbd957402013-10-03 11:38:39 -04003751 "translucent".equals(mode) ? MODE_TRANSLUCENT :
John Spurlock3c875662013-08-31 15:07:25 -04003752 "semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
John Spurlock0ff62e02014-07-22 16:15:08 -04003753 "transparent".equals(mode) ? MODE_TRANSPARENT :
3754 "warning".equals(mode) ? MODE_WARNING :
John Spurlock3c875662013-08-31 15:07:25 -04003755 -1;
3756 if (barMode != -1) {
3757 boolean animate = true;
3758 if (mStatusBarView != null) {
3759 mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
3760 }
3761 if (mNavigationBarView != null) {
3762 mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
3763 }
3764 }
3765 }
3766 }
3767
3768 private void dispatchDemoCommandToView(String command, Bundle args, int id) {
3769 if (mStatusBarView == null) return;
3770 View v = mStatusBarView.findViewById(id);
3771 if (v instanceof DemoMode) {
3772 ((DemoMode)v).dispatchDemoCommand(command, args);
3773 }
3774 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003775
Jorim Jaggiecbab362014-04-23 16:13:15 +02003776 /**
3777 * @return The {@link StatusBarState} the status bar is in.
3778 */
3779 public int getBarState() {
3780 return mState;
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003781 }
3782
Chris Wren16895942015-06-23 11:22:20 -04003783 @Override
Yorke Leee4ea6ab2016-03-03 14:51:49 -08003784 public boolean isPanelFullyCollapsed() {
Chris Wren16895942015-06-23 11:22:20 -04003785 return mNotificationPanel.isFullyCollapsed();
3786 }
3787
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003788 public void showKeyguard() {
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003789 if (mLaunchTransitionFadingAway) {
3790 mNotificationPanel.animate().cancel();
Selim Cinek37c110f2015-05-22 12:38:44 -07003791 onLaunchTransitionFadingEnded();
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003792 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01003793 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07003794 if (mUserSwitcherController != null && mUserSwitcherController.useFullscreenUserSwitcher()) {
3795 setBarState(StatusBarState.FULLSCREEN_USER_SWITCHER);
3796 } else {
3797 setBarState(StatusBarState.KEYGUARD);
3798 }
Jorim Jaggi98f85302014-08-07 17:45:04 +02003799 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003800 if (!mDeviceInteractive) {
Jorim Jaggid41083a2014-09-12 02:54:40 +02003801
3802 // If the screen is off already, we need to disable touch events because these might
3803 // collapse the panel after we expanded it, and thus we would end up with a blank
3804 // Keyguard.
3805 mNotificationPanel.setTouchDisabled(true);
3806 }
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07003807 if (mState == StatusBarState.KEYGUARD) {
3808 instantExpandNotificationsPanel();
3809 } else if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
3810 instantCollapseNotificationPanel();
3811 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003812 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003813 if (mDraggedDownRow != null) {
3814 mDraggedDownRow.setUserLocked(false);
Selim Cinekb5605e52015-02-20 18:21:41 +01003815 mDraggedDownRow.notifyHeightChanged(false /* needsAnimation */);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003816 mDraggedDownRow = null;
3817 }
Adrian Roos3aec6382016-02-05 14:19:01 -08003818 mPendingRemoteInputView = null;
Jorim Jaggi19695d92015-07-20 15:51:40 -07003819 mAssistManager.onLockscreenShown();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003820 }
3821
Selim Cinek37c110f2015-05-22 12:38:44 -07003822 private void onLaunchTransitionFadingEnded() {
3823 mNotificationPanel.setAlpha(1.0f);
Selim Cinek372d1bd2015-08-14 13:19:37 -07003824 mNotificationPanel.onAffordanceLaunchEnded();
3825 releaseGestureWakeLock();
Selim Cinek37c110f2015-05-22 12:38:44 -07003826 runLaunchTransitionEndRunnable();
3827 mLaunchTransitionFadingAway = false;
3828 mScrimController.forceHideScrims(false /* hide */);
Adrian Roos52738322016-01-29 08:49:21 -08003829 updateMediaMetaData(true /* metaDataChanged */, true);
Selim Cinek37c110f2015-05-22 12:38:44 -07003830 }
3831
Selim Cinek36b02232016-05-11 23:07:05 -04003832 @Override
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003833 public boolean isCollapsing() {
3834 return mNotificationPanel.isCollapsing();
3835 }
3836
Selim Cinek36b02232016-05-11 23:07:05 -04003837 @Override
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003838 public void addPostCollapseAction(Runnable r) {
3839 mPostCollapseRunnables.add(r);
3840 }
3841
Selim Cinekbaa23272014-07-08 18:01:07 +02003842 public boolean isInLaunchTransition() {
3843 return mNotificationPanel.isLaunchTransitionRunning()
3844 || mNotificationPanel.isLaunchTransitionFinished();
3845 }
3846
3847 /**
3848 * Fades the content of the keyguard away after the launch transition is done.
3849 *
3850 * @param beforeFading the runnable to be run when the circle is fully expanded and the fading
3851 * starts
3852 * @param endRunnable the runnable to be run when the transition is done
3853 */
3854 public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003855 Runnable endRunnable) {
Jorim Jaggi826730a2014-12-08 21:05:13 +01003856 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003857 mLaunchTransitionEndRunnable = endRunnable;
Selim Cinekbaa23272014-07-08 18:01:07 +02003858 Runnable hideRunnable = new Runnable() {
3859 @Override
3860 public void run() {
3861 mLaunchTransitionFadingAway = true;
3862 if (beforeFading != null) {
3863 beforeFading.run();
3864 }
Selim Cinek37c110f2015-05-22 12:38:44 -07003865 mScrimController.forceHideScrims(true /* hide */);
Adrian Roos52738322016-01-29 08:49:21 -08003866 updateMediaMetaData(false, true);
Selim Cinekbaa23272014-07-08 18:01:07 +02003867 mNotificationPanel.setAlpha(1);
3868 mNotificationPanel.animate()
3869 .alpha(0)
3870 .setStartDelay(FADE_KEYGUARD_START_DELAY)
3871 .setDuration(FADE_KEYGUARD_DURATION)
3872 .withLayer()
3873 .withEndAction(new Runnable() {
3874 @Override
3875 public void run() {
Selim Cinek37c110f2015-05-22 12:38:44 -07003876 onLaunchTransitionFadingEnded();
Selim Cinekbaa23272014-07-08 18:01:07 +02003877 }
3878 });
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003879 mIconController.appTransitionStarting(SystemClock.uptimeMillis(),
3880 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Selim Cinekbaa23272014-07-08 18:01:07 +02003881 }
3882 };
3883 if (mNotificationPanel.isLaunchTransitionRunning()) {
3884 mNotificationPanel.setLaunchTransitionEndRunnable(hideRunnable);
3885 } else {
3886 hideRunnable.run();
3887 }
3888 }
3889
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003890 /**
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07003891 * Fades the content of the Keyguard while we are dozing and makes it invisible when finished
3892 * fading.
3893 */
3894 public void fadeKeyguardWhilePulsing() {
3895 mNotificationPanel.animate()
3896 .alpha(0f)
3897 .setStartDelay(0)
3898 .setDuration(FADE_KEYGUARD_DURATION_PULSING)
Jorim Jaggiab45a212015-08-20 16:59:44 -07003899 .setInterpolator(ScrimController.KEYGUARD_FADE_OUT_INTERPOLATOR)
3900 .start();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07003901 }
3902
3903 /**
Jorim Jaggi826730a2014-12-08 21:05:13 +01003904 * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
3905 * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
3906 * because the launched app crashed or something else went wrong.
3907 */
3908 public void startLaunchTransitionTimeout() {
3909 mHandler.sendEmptyMessageDelayed(MSG_LAUNCH_TRANSITION_TIMEOUT,
3910 LAUNCH_TRANSITION_TIMEOUT_MS);
3911 }
3912
3913 private void onLaunchTransitionTimeout() {
3914 Log.w(TAG, "Launch transition: Timeout!");
Selim Cinek372d1bd2015-08-14 13:19:37 -07003915 mNotificationPanel.onAffordanceLaunchEnded();
3916 releaseGestureWakeLock();
Jorim Jaggi826730a2014-12-08 21:05:13 +01003917 mNotificationPanel.resetViews();
3918 }
3919
3920 private void runLaunchTransitionEndRunnable() {
3921 if (mLaunchTransitionEndRunnable != null) {
3922 Runnable r = mLaunchTransitionEndRunnable;
3923
3924 // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
3925 // which would lead to infinite recursion. Protect against it.
3926 mLaunchTransitionEndRunnable = null;
3927 r.run();
3928 }
3929 }
3930
3931 /**
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003932 * @return true if we would like to stay in the shade, false if it should go away entirely
3933 */
3934 public boolean hideKeyguard() {
3935 boolean staying = mLeaveOpenOnKeyguardHide;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003936 setBarState(StatusBarState.SHADE);
Adrian Roos3aec6382016-02-05 14:19:01 -08003937 View viewToClick = null;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003938 if (mLeaveOpenOnKeyguardHide) {
3939 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggi37c11802015-08-18 20:27:54 -07003940 long delay = calculateGoingToFullShadeDelay();
3941 mNotificationPanel.animateToFullShade(delay);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003942 if (mDraggedDownRow != null) {
3943 mDraggedDownRow.setUserLocked(false);
3944 mDraggedDownRow = null;
3945 }
Adrian Roos3aec6382016-02-05 14:19:01 -08003946 viewToClick = mPendingRemoteInputView;
3947 mPendingRemoteInputView = null;
Jorim Jaggi37c11802015-08-18 20:27:54 -07003948
3949 // Disable layout transitions in navbar for this transition because the load is just
3950 // too heavy for the CPU and GPU on any device.
3951 if (mNavigationBarView != null) {
3952 mNavigationBarView.setLayoutTransitionsEnabled(false);
3953 mNavigationBarView.postDelayed(new Runnable() {
3954 @Override
3955 public void run() {
3956 mNavigationBarView.setLayoutTransitionsEnabled(true);
3957 }
3958 }, delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
3959 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003960 } else {
3961 instantCollapseNotificationPanel();
3962 }
Jorim Jaggi98f85302014-08-07 17:45:04 +02003963 updateKeyguardState(staying, false /* fromShadeLocked */);
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +01003964
Adrian Roos3aec6382016-02-05 14:19:01 -08003965 if (viewToClick != null) {
3966 viewToClick.callOnClick();
3967 }
3968
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +01003969 // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
3970 // visibilities so next time we open the panel we know the correct height already.
3971 if (mQSPanel != null) {
3972 mQSPanel.refreshAllTiles();
3973 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01003974 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Selim Cinek372d1bd2015-08-14 13:19:37 -07003975 releaseGestureWakeLock();
3976 mNotificationPanel.onAffordanceLaunchEnded();
Jorim Jaggi52429b42015-09-03 19:58:19 -07003977 mNotificationPanel.animate().cancel();
Jorim Jaggi90978852015-08-18 19:55:53 -07003978 mNotificationPanel.setAlpha(1f);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003979 return staying;
3980 }
3981
Selim Cinek372d1bd2015-08-14 13:19:37 -07003982 private void releaseGestureWakeLock() {
3983 if (mGestureWakeLock.isHeld()) {
3984 mGestureWakeLock.release();
3985 }
3986 }
3987
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003988 public long calculateGoingToFullShadeDelay() {
3989 return mKeyguardFadingAwayDelay + mKeyguardFadingAwayDuration;
Jorim Jaggi15682502014-04-23 12:01:36 +02003990 }
3991
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003992 /**
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003993 * Notifies the status bar that Keyguard is going away very soon.
3994 */
3995 public void keyguardGoingAway() {
3996
3997 // Treat Keyguard exit animation as an app transition to achieve nice transition for status
3998 // bar.
Adrian Roos46df1ca2015-09-11 12:38:43 -07003999 mKeyguardGoingAway = true;
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004000 mIconController.appTransitionPending();
4001 }
4002
4003 /**
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004004 * Notifies the status bar the Keyguard is fading away with the specified timings.
4005 *
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004006 * @param startTime the start time of the animations in uptime millis
4007 * @param delay the precalculated animation delay in miliseconds
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004008 * @param fadeoutDuration the duration of the exit animation, in milliseconds
4009 */
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004010 public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration) {
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004011 mKeyguardFadingAway = true;
4012 mKeyguardFadingAwayDelay = delay;
4013 mKeyguardFadingAwayDuration = fadeoutDuration;
4014 mWaitingForKeyguardExit = false;
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004015 mIconController.appTransitionStarting(
4016 startTime + fadeoutDuration
4017 - StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION,
4018 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07004019 disable(mDisabledUnmodified1, mDisabledUnmodified2, fadeoutDuration > 0 /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004020 }
4021
Jorim Jaggi416493b2014-09-13 03:57:32 +02004022 public boolean isKeyguardFadingAway() {
4023 return mKeyguardFadingAway;
4024 }
4025
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004026 /**
4027 * Notifies that the Keyguard fading away animation is done.
4028 */
4029 public void finishKeyguardFadingAway() {
4030 mKeyguardFadingAway = false;
Adrian Roos46df1ca2015-09-11 12:38:43 -07004031 mKeyguardGoingAway = false;
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004032 }
4033
Adrian Roosd322f1a2015-04-23 15:19:45 -07004034 public void stopWaitingForKeyguardExit() {
4035 mWaitingForKeyguardExit = false;
4036 }
4037
Jorim Jaggi15682502014-04-23 12:01:36 +02004038 private void updatePublicMode() {
Tony Mak92c989d2016-04-19 14:02:44 +01004039 boolean isPublic = false;
4040 if (mStatusBarKeyguardViewManager.isShowing()) {
4041 for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) {
4042 UserInfo userInfo = mCurrentProfiles.valueAt(i);
4043 if (mStatusBarKeyguardViewManager.isSecure(userInfo.id)) {
4044 isPublic = true;
4045 break;
4046 }
4047 }
4048 }
4049 setLockscreenPublicMode(isPublic);
Jorim Jaggi15682502014-04-23 12:01:36 +02004050 }
4051
Rakesh Iyer2790a372016-01-22 15:33:39 -08004052 protected void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02004053 if (mState == StatusBarState.KEYGUARD) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02004054 mKeyguardIndicationController.setVisible(true);
Selim Cinek4c6969a2014-05-26 19:22:17 +02004055 mNotificationPanel.resetViews();
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004056 if (mKeyguardUserSwitcher != null) {
4057 mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
4058 }
Selim Cinek80c2abe2015-06-17 15:37:30 -07004059 mStatusBarView.removePendingHideExpandedRunnables();
Jorim Jaggi15682502014-04-23 12:01:36 +02004060 } else {
Adrian Roos12c1ef52014-06-04 13:54:08 +02004061 mKeyguardIndicationController.setVisible(false);
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004062 if (mKeyguardUserSwitcher != null) {
4063 mKeyguardUserSwitcher.setKeyguard(false,
4064 goingToFullShade ||
4065 mState == StatusBarState.SHADE_LOCKED ||
4066 fromShadeLocked);
4067 }
Jorim Jaggi15682502014-04-23 12:01:36 +02004068 }
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004069 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02004070 mScrimController.setKeyguardShowing(true);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004071 } else {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02004072 mScrimController.setKeyguardShowing(false);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004073 }
Nicolas Prevot1dbbe7d2016-05-17 12:52:54 +01004074 mIconPolicy.notifyKeyguardShowingChanged();
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004075 mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
John Spurlockbf370992014-06-17 13:58:31 -04004076 updateDozingState();
Jorim Jaggi15682502014-04-23 12:01:36 +02004077 updatePublicMode();
Selim Cinekd35c2792016-01-21 13:20:57 -08004078 updateStackScrollerState(goingToFullShade, fromShadeLocked);
Christoph Studer37fe6932014-05-26 13:10:30 +02004079 updateNotifications();
Jorim Jaggia6310292014-04-16 14:11:52 +02004080 checkBarModes();
Adrian Roos52738322016-01-29 08:49:21 -08004081 updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
John Spurlock657c62c2014-07-22 12:18:09 -04004082 mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
4083 mStatusBarKeyguardViewManager.isSecure());
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004084 }
4085
John Spurlockbf370992014-06-17 13:58:31 -04004086 private void updateDozingState() {
Jorim Jaggi4e857f42014-11-17 19:14:04 +01004087 boolean animate = !mDozing && mDozeScrimController.isPulsing();
4088 mNotificationPanel.setDozing(mDozing, animate);
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004089 mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation);
Jorim Jaggi048af1f2014-11-11 22:51:10 +01004090 mScrimController.setDozing(mDozing);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004091
4092 // Immediately abort the dozing from the doze scrim controller in case of wake-and-unlock
4093 // for pulsing so the Keyguard fade-out animation scrim can take over.
4094 mDozeScrimController.setDozing(mDozing &&
4095 mFingerprintUnlockController.getMode()
4096 != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING, animate);
John Spurlockbf370992014-06-17 13:58:31 -04004097 }
4098
Selim Cinekd35c2792016-01-21 13:20:57 -08004099 public void updateStackScrollerState(boolean goingToFullShade, boolean fromShadeLocked) {
John Spurlock4b3bda22014-05-22 14:32:20 -04004100 if (mStackScroller == null) return;
Selim Cinek1408eb52014-06-02 14:45:38 +02004101 boolean onKeyguard = mState == StatusBarState.KEYGUARD;
Jorim Jaggiae441282014-08-01 02:45:18 +02004102 mStackScroller.setHideSensitive(isLockscreenPublicMode(), goingToFullShade);
Selim Cinekd35c2792016-01-21 13:20:57 -08004103 mStackScroller.setDimmed(onKeyguard, fromShadeLocked /* animate */);
Selim Cinek1408eb52014-06-02 14:45:38 +02004104 mStackScroller.setExpandingEnabled(!onKeyguard);
Selim Cineka32ab602014-06-11 15:06:01 +02004105 ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
4106 mStackScroller.setActivatedChild(null);
4107 if (activatedChild != null) {
4108 activatedChild.makeInactive(false /* animate */);
4109 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004110 }
4111
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004112 public void userActivity() {
Jorim Jaggib690f0d2014-07-03 23:25:44 +02004113 if (mState == StatusBarState.KEYGUARD) {
4114 mKeyguardViewMediatorCallback.userActivity();
4115 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004116 }
4117
Jorim Jaggidf993512014-05-13 23:06:35 +02004118 public boolean interceptMediaKey(KeyEvent event) {
4119 return mState == StatusBarState.KEYGUARD
4120 && mStatusBarKeyguardViewManager.interceptMediaKey(event);
4121 }
4122
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02004123 public boolean onMenuPressed() {
Selim Cinek28540192016-02-19 17:25:08 -08004124 if (mDeviceInteractive && mState != StatusBarState.SHADE
4125 && mStatusBarKeyguardViewManager.shouldDismissOnMenuPressed()) {
4126 animateCollapsePanels(
4127 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
4128 return true;
4129 }
4130 return false;
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02004131 }
4132
Selim Cinek372d1bd2015-08-14 13:19:37 -07004133 public void endAffordanceLaunch() {
4134 releaseGestureWakeLock();
4135 mNotificationPanel.onAffordanceLaunchEnded();
4136 }
4137
Jorim Jaggie5c7a892014-04-10 20:37:32 +02004138 public boolean onBackPressed() {
Adrian Roos0002a452014-07-03 13:46:07 +02004139 if (mStatusBarKeyguardViewManager.onBackPressed()) {
Jorim Jaggie5c7a892014-04-10 20:37:32 +02004140 return true;
4141 }
Adrian Roos0002a452014-07-03 13:46:07 +02004142 if (mNotificationPanel.isQsExpanded()) {
John Spurlockf7ae4422014-08-01 12:45:18 -04004143 if (mNotificationPanel.isQsDetailShowing()) {
4144 mNotificationPanel.closeQsDetail();
4145 } else {
4146 mNotificationPanel.animateCloseQs();
4147 }
Adrian Roos0002a452014-07-03 13:46:07 +02004148 return true;
4149 }
4150 if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) {
4151 animateCollapsePanels();
4152 return true;
4153 }
4154 return false;
Jorim Jaggie5c7a892014-04-10 20:37:32 +02004155 }
4156
Jorim Jaggi34250762014-07-03 23:51:19 +02004157 public boolean onSpacePressed() {
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004158 if (mDeviceInteractive && mState != StatusBarState.SHADE) {
Jorim Jaggi4eedc1d2014-10-27 13:45:56 +01004159 animateCollapsePanels(
4160 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
Jorim Jaggi34250762014-07-03 23:51:19 +02004161 return true;
4162 }
4163 return false;
4164 }
4165
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004166 private void showBouncer() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02004167 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekbaa23272014-07-08 18:01:07 +02004168 mWaitingForKeyguardExit = mStatusBarKeyguardViewManager.isShowing();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004169 mStatusBarKeyguardViewManager.dismiss();
4170 }
4171 }
4172
4173 private void instantExpandNotificationsPanel() {
Jorim Jaggic357ca22014-04-25 14:56:15 +02004174
Jorim Jaggi0a27be82014-06-11 03:22:39 +02004175 // Make our window larger and the panel expanded.
Jorim Jaggifa505a72014-04-28 20:04:11 +02004176 makeExpandedVisible(true);
Oren Blasberg8d3fea12015-07-10 14:21:44 -07004177 mNotificationPanel.expand(false /* animate */);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004178 }
Adrian Roos5a46cd32014-04-03 16:51:58 +02004179
Jorim Jaggia005f1b2014-04-16 19:06:10 +02004180 private void instantCollapseNotificationPanel() {
Selim Cinek6bb4a9b2014-10-09 17:48:05 -07004181 mNotificationPanel.instantCollapse();
Jorim Jaggia005f1b2014-04-16 19:06:10 +02004182 }
4183
Jorim Jaggid4a57442014-04-10 02:45:55 +02004184 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02004185 public void onActivated(ActivatableNotificationView view) {
Christoph Studerb0183992014-12-22 21:02:26 +01004186 EventLogTags.writeSysuiLockscreenGesture(
4187 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE,
4188 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
Adrian Roos12c1ef52014-06-04 13:54:08 +02004189 mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
Selim Cineka32ab602014-06-11 15:06:01 +02004190 ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
4191 if (previousView != null) {
4192 previousView.makeInactive(true /* animate */);
4193 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004194 mStackScroller.setActivatedChild(view);
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02004195 }
4196
Jorim Jaggiecbab362014-04-23 16:13:15 +02004197 /**
4198 * @param state The {@link StatusBarState} to set.
4199 */
4200 public void setBarState(int state) {
Christoph Studer2231c6e2014-12-19 12:40:13 +01004201 // If we're visible and switched to SHADE_LOCKED (the user dragged
4202 // down on the lockscreen), clear notification LED, vibration,
4203 // ringing.
4204 // Other transitions are covered in handleVisibleToUserChanged().
Selim Cinek6577cae2015-08-31 16:15:49 -07004205 if (state != mState && mVisible && (state == StatusBarState.SHADE_LOCKED
4206 || (state == StatusBarState.SHADE && isGoingToNotificationShade()))) {
4207 clearNotificationEffects();
Christoph Studer1f32c652014-11-26 15:32:20 +01004208 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02004209 mState = state;
Selim Cinek9c4c4142015-12-04 16:44:56 -08004210 mGroupManager.setStatusBarState(state);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004211 mFalsingManager.setStatusBarState(state);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004212 mStatusBarWindowManager.setStatusBarState(state);
Jorim Jaggi83969702015-06-05 14:59:24 -07004213 updateDozing();
Jorim Jaggiecbab362014-04-23 16:13:15 +02004214 }
4215
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02004216 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02004217 public void onActivationReset(ActivatableNotificationView view) {
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004218 if (view == mStackScroller.getActivatedChild()) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02004219 mKeyguardIndicationController.hideTransientIndication();
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004220 mStackScroller.setActivatedChild(null);
4221 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004222 }
4223
4224 public void onTrackingStarted() {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02004225 runPostCollapseRunnables();
Jorim Jaggi90129582014-06-02 14:44:49 +02004226 }
4227
Selim Cinekdbbcfbe2014-10-24 17:52:35 +02004228 public void onClosingFinished() {
4229 runPostCollapseRunnables();
4230 }
4231
Jorim Jaggi90129582014-06-02 14:44:49 +02004232 public void onUnlockHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004233 mFalsingManager.onUnlockHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004234 mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
Jorim Jaggi90129582014-06-02 14:44:49 +02004235 }
4236
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004237 public void onHintFinished() {
Jorim Jaggi93a2bb22014-06-02 19:57:28 +02004238 // Delay the reset a bit so the user can read the text.
Adrian Roos12c1ef52014-06-04 13:54:08 +02004239 mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004240 }
4241
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004242 public void onCameraHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004243 mFalsingManager.onCameraHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004244 mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004245 }
4246
Selim Cineke70d6532015-04-24 16:46:13 -07004247 public void onVoiceAssistHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004248 mFalsingManager.onLeftAffordanceHintStarted();
Selim Cineke70d6532015-04-24 16:46:13 -07004249 mKeyguardIndicationController.showTransientIndication(R.string.voice_hint);
4250 }
4251
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004252 public void onPhoneHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004253 mFalsingManager.onLeftAffordanceHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004254 mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004255 }
4256
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004257 public void onTrackingStopped(boolean expand) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004258 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Selim Cineke8bae622015-07-15 13:24:06 -07004259 if (!expand && !mUnlockMethodCache.canSkipBouncer()) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004260 showBouncer();
4261 }
4262 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004263 }
4264
4265 @Override
Selim Cinek5f71bee2015-11-18 10:25:23 -08004266 protected int getMaxKeyguardNotifications(boolean recompute) {
4267 if (recompute) {
4268 mMaxKeyguardNotifications = Math.max(1,
4269 mNotificationPanel.computeMaxKeyguardNotifications(
4270 mMaxAllowedKeyguardNotifications));
4271 return mMaxKeyguardNotifications;
4272 }
4273 return mMaxKeyguardNotifications;
4274 }
4275
4276 public int getMaxKeyguardNotifications() {
4277 return getMaxKeyguardNotifications(false /* recompute */);
Jorim Jaggid4a57442014-04-10 02:45:55 +02004278 }
4279
Jorim Jaggia6310292014-04-16 14:11:52 +02004280 public NavigationBarView getNavigationBarView() {
4281 return mNavigationBarView;
4282 }
4283
Jorim Jaggiecbab362014-04-23 16:13:15 +02004284 // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
4285
4286 @Override
Christoph Studerb0183992014-12-22 21:02:26 +01004287 public boolean onDraggedDown(View startingChild, int dragLengthY) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02004288 if (hasActiveNotifications()) {
Christoph Studerb0183992014-12-22 21:02:26 +01004289 EventLogTags.writeSysuiLockscreenGesture(
4290 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE,
4291 (int) (dragLengthY / mDisplayMetrics.density),
4292 0 /* velocityDp - N/A */);
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004293
4294 // We have notifications, go to locked shade.
4295 goToLockedShade(startingChild);
4296 return true;
4297 } else {
4298
4299 // No notifications - abort gesture.
4300 return false;
4301 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02004302 }
4303
4304 @Override
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004305 public void onDragDownReset() {
4306 mStackScroller.setDimmed(true /* dimmed */, true /* animated */);
Selim Cinek177fd432015-11-18 11:53:47 -08004307 mStackScroller.resetScrollPosition();
Jorim Jaggiecbab362014-04-23 16:13:15 +02004308 }
4309
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004310 @Override
Selim Cinek177fd432015-11-18 11:53:47 -08004311 public void onCrossedThreshold(boolean above) {
4312 mStackScroller.setDimmed(!above /* dimmed */, true /* animate */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004313 }
4314
Selim Cinek1408eb52014-06-02 14:45:38 +02004315 @Override
4316 public void onTouchSlopExceeded() {
4317 mStackScroller.removeLongPressCallback();
4318 }
4319
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004320 @Override
4321 public void setEmptyDragAmount(float amount) {
4322 mNotificationPanel.setEmptyDragAmount(amount);
4323 }
4324
Jorim Jaggiecbab362014-04-23 16:13:15 +02004325 /**
4326 * If secure with redaction: Show bouncer, go to unlocked shade.
4327 *
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004328 * <p>If secure without redaction or no security: Go to {@link StatusBarState#SHADE_LOCKED}.</p>
Jorim Jaggiecbab362014-04-23 16:13:15 +02004329 *
4330 * @param expandView The view to expand after going to the shade.
4331 */
4332 public void goToLockedShade(View expandView) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004333 ExpandableNotificationRow row = null;
Jorim Jaggiecbab362014-04-23 16:13:15 +02004334 if (expandView instanceof ExpandableNotificationRow) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004335 row = (ExpandableNotificationRow) expandView;
Selim Cinekcb24ab82016-02-25 12:49:08 -08004336 row.setUserExpanded(true /* userExpanded */, true /* allowChildExpansion */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004337 }
Adrian Roosaee70462014-09-03 16:27:39 +02004338 boolean fullShadeNeedsBouncer = !userAllowsPrivateNotificationsInPublic(mCurrentUserId)
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004339 || !mShowLockscreenNotifications || mFalsingManager.shouldEnforceBouncer();
Adrian Roosaee70462014-09-03 16:27:39 +02004340 if (isLockscreenPublicMode() && fullShadeNeedsBouncer) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02004341 mLeaveOpenOnKeyguardHide = true;
4342 showBouncer();
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004343 mDraggedDownRow = row;
Adrian Roos3aec6382016-02-05 14:19:01 -08004344 mPendingRemoteInputView = null;
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004345 } else {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004346 mNotificationPanel.animateToFullShade(0 /* delay */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004347 setBarState(StatusBarState.SHADE_LOCKED);
Jorim Jaggi98f85302014-08-07 17:45:04 +02004348 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004349 }
4350 }
4351
Selim Cinek570981d2015-12-01 11:37:01 -08004352 @Override
Mady Mellor8e8a69e2016-03-14 12:30:10 -07004353 public void onLockedNotificationImportanceChange(OnDismissAction dismissAction) {
4354 mLeaveOpenOnKeyguardHide = true;
4355 dismissKeyguardThenExecute(dismissAction, true /* afterKeyguardGone */);
4356 }
4357
4358 @Override
Adrian Roos3aec6382016-02-05 14:19:01 -08004359 protected void onLockedRemoteInput(ExpandableNotificationRow row, View clicked) {
4360 mLeaveOpenOnKeyguardHide = true;
4361 showBouncer();
4362 mPendingRemoteInputView = clicked;
4363 }
4364
4365 @Override
Ricky Waicd35def2016-05-03 11:07:07 +01004366 protected boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender,
4367 String notificationKey) {
4368 // Clear pending remote view, as we do not want to trigger pending remote input view when
4369 // it's called by other code
4370 mPendingWorkRemoteInputView = null;
4371 return super.startWorkChallengeIfNecessary(userId, intendSender, notificationKey);
4372 }
4373
4374 @Override
4375 protected void onLockedWorkRemoteInput(int userId, ExpandableNotificationRow row,
4376 View clicked) {
4377 // Collapse notification and show work challenge
4378 animateCollapsePanels();
4379 startWorkChallengeIfNecessary(userId, null, null);
4380 // Add pending remote input view after starting work challenge, as starting work challenge
4381 // will clear all previous pending review view
4382 mPendingWorkRemoteInputView = clicked;
4383 }
4384
4385 @Override
4386 protected void onWorkChallengeUnlocked() {
4387 if (mPendingWorkRemoteInputView != null) {
4388 final View pendingWorkRemoteInputView = mPendingWorkRemoteInputView;
4389 // Expand notification panel and the notification row, then click on remote input view
4390 final Runnable clickPendingViewRunnable = new Runnable() {
4391 @Override
4392 public void run() {
4393 if (mPendingWorkRemoteInputView != null) {
4394 final View pendingWorkRemoteInputView = mPendingWorkRemoteInputView;
4395 ViewParent p = pendingWorkRemoteInputView.getParent();
4396 while (p != null) {
4397 if (p instanceof ExpandableNotificationRow) {
4398 final ExpandableNotificationRow row = (ExpandableNotificationRow) p;
4399 ViewParent viewParent = row.getParent();
4400 if (viewParent instanceof NotificationStackScrollLayout) {
4401 final NotificationStackScrollLayout scrollLayout =
4402 (NotificationStackScrollLayout) viewParent;
4403 row.makeActionsVisibile();
4404 row.post(new Runnable() {
4405 @Override
4406 public void run() {
4407 final Runnable finishScrollingCallback = new Runnable()
4408 {
4409 @Override
4410 public void run() {
4411 mPendingWorkRemoteInputView.callOnClick();
4412 mPendingWorkRemoteInputView = null;
4413 scrollLayout.setFinishScrollingCallback(null);
4414 }
4415 };
4416 if (scrollLayout.scrollTo(row)) {
4417 // It scrolls! So call it when it's finished.
4418 scrollLayout.setFinishScrollingCallback(
4419 finishScrollingCallback);
4420 } else {
4421 // It does not scroll, so call it now!
4422 finishScrollingCallback.run();
4423 }
4424 }
4425 });
4426 }
4427 break;
4428 }
4429 p = p.getParent();
4430 }
4431 }
4432 }
4433 };
4434 mNotificationPanel.getViewTreeObserver().addOnGlobalLayoutListener(
4435 new ViewTreeObserver.OnGlobalLayoutListener() {
4436 @Override
4437 public void onGlobalLayout() {
4438 if (mNotificationPanel.mStatusBar.getStatusBarWindow()
4439 .getHeight() != mNotificationPanel.mStatusBar
4440 .getStatusBarHeight()) {
4441 mNotificationPanel.getViewTreeObserver()
4442 .removeOnGlobalLayoutListener(this);
4443 mNotificationPanel.post(clickPendingViewRunnable);
4444 }
4445 }
4446 });
4447 instantExpandNotificationsPanel();
4448 }
4449 }
4450
4451 @Override
Selim Cinek31aada42015-12-18 17:51:15 -08004452 public void onExpandClicked(Entry clickedEntry, boolean nowExpanded) {
4453 mHeadsUpManager.setExpanded(clickedEntry, nowExpanded);
Selim Cinek570981d2015-12-01 11:37:01 -08004454 if (mState == StatusBarState.KEYGUARD && nowExpanded) {
Selim Cinek31aada42015-12-18 17:51:15 -08004455 goToLockedShade(clickedEntry.row);
Selim Cinek570981d2015-12-01 11:37:01 -08004456 }
4457 }
4458
Adrian Roos5a46cd32014-04-03 16:51:58 +02004459 /**
Jorim Jaggi6539a832014-06-03 23:33:09 +02004460 * Goes back to the keyguard after hanging around in {@link StatusBarState#SHADE_LOCKED}.
4461 */
4462 public void goToKeyguard() {
4463 if (mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekd9acca52014-09-01 22:33:25 +02004464 mStackScroller.onGoToKeyguard();
Jorim Jaggi6539a832014-06-03 23:33:09 +02004465 setBarState(StatusBarState.KEYGUARD);
Jorim Jaggi98f85302014-08-07 17:45:04 +02004466 updateKeyguardState(false /* goingToFullShade */, true /* fromShadeLocked*/);
Jorim Jaggi6539a832014-06-03 23:33:09 +02004467 }
4468 }
4469
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004470 public long getKeyguardFadingAwayDelay() {
4471 return mKeyguardFadingAwayDelay;
4472 }
4473
4474 public long getKeyguardFadingAwayDuration() {
4475 return mKeyguardFadingAwayDuration;
4476 }
4477
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004478 @Override
4479 public void setBouncerShowing(boolean bouncerShowing) {
4480 super.setBouncerShowing(bouncerShowing);
Adrian Roosd0b2f7d2015-04-29 13:36:12 -07004481 mStatusBarView.setBouncerShowing(bouncerShowing);
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01004482 disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004483 }
4484
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004485 public void onStartedGoingToSleep() {
4486 mStartedGoingToSleep = true;
4487 }
4488
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004489 public void onFinishedGoingToSleep() {
Selim Cinek372d1bd2015-08-14 13:19:37 -07004490 mNotificationPanel.onAffordanceLaunchEnded();
4491 releaseGestureWakeLock();
4492 mLaunchCameraOnScreenTurningOn = false;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004493 mStartedGoingToSleep = false;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004494 mDeviceInteractive = false;
4495 mWakeUpComingFromTouch = false;
4496 mWakeUpTouchLocation = null;
Jorim Jaggi75c95042014-05-16 19:09:59 +02004497 mStackScroller.setAnimationsEnabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01004498 updateVisibleToUser();
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004499 if (mLaunchCameraOnFinishedGoingToSleep) {
4500 mLaunchCameraOnFinishedGoingToSleep = false;
4501
4502 // This gets executed before we will show Keyguard, so post it in order that the state
4503 // is correct.
4504 mHandler.post(new Runnable() {
4505 @Override
4506 public void run() {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004507 onCameraLaunchGestureDetected(mLastCameraLaunchSource);
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004508 }
4509 });
4510 }
Jorim Jaggi75c95042014-05-16 19:09:59 +02004511 }
4512
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004513 public void onStartedWakingUp() {
4514 mDeviceInteractive = true;
Jorim Jaggi75c95042014-05-16 19:09:59 +02004515 mStackScroller.setAnimationsEnabled(true);
Jorim Jaggid41083a2014-09-12 02:54:40 +02004516 mNotificationPanel.setTouchDisabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01004517 updateVisibleToUser();
Jorim Jaggi75c95042014-05-16 19:09:59 +02004518 }
John Spurlockd08f91f2014-05-23 11:00:34 -04004519
Jorim Jaggi93739112015-08-13 15:53:14 -07004520 public void onScreenTurningOn() {
Selim Cinek1b6f8192015-09-03 16:01:53 -07004521 mScreenTurningOn = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004522 mFalsingManager.onScreenTurningOn();
Jorim Jaggi93739112015-08-13 15:53:14 -07004523 mNotificationPanel.onScreenTurningOn();
Selim Cinek372d1bd2015-08-14 13:19:37 -07004524 if (mLaunchCameraOnScreenTurningOn) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004525 mNotificationPanel.launchCamera(false, mLastCameraLaunchSource);
Selim Cinek372d1bd2015-08-14 13:19:37 -07004526 mLaunchCameraOnScreenTurningOn = false;
4527 }
Jorim Jaggi93739112015-08-13 15:53:14 -07004528 }
4529
Selim Cinek69ff8af2015-08-25 19:03:48 -07004530 private void vibrateForCameraGesture() {
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004531 // Make sure to pass -1 for repeat so VibratorService doesn't stop us when going to sleep.
Jorim Jaggi75b25972015-10-21 14:51:10 +02004532 mVibrator.vibrate(new long[]{0, 750L}, -1 /* repeat */);
Selim Cinek69ff8af2015-08-25 19:03:48 -07004533 }
4534
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004535 public void onScreenTurnedOn() {
Selim Cinek1b6f8192015-09-03 16:01:53 -07004536 mScreenTurningOn = false;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004537 mDozeScrimController.onScreenTurnedOn();
4538 }
4539
Jason Monk815e0572014-08-12 17:26:36 -04004540 /**
Jorim Jaggi75b25972015-10-21 14:51:10 +02004541 * Handles long press for back button. This exits screen pinning.
Jason Monk815e0572014-08-12 17:26:36 -04004542 */
Jorim Jaggi75b25972015-10-21 14:51:10 +02004543 private boolean handleLongPressBack() {
Jason Monk62515be2014-05-21 16:06:19 -04004544 try {
4545 IActivityManager activityManager = ActivityManagerNative.getDefault();
Jorim Jaggi75b25972015-10-21 14:51:10 +02004546 if (activityManager.isInLockTaskMode()) {
Andrii Kulian0f051f52016-04-14 00:41:51 -07004547 activityManager.stopSystemLockTaskMode();
Jorim Jaggi75b25972015-10-21 14:51:10 +02004548
4549 // When exiting refresh disabled flags.
4550 mNavigationBarView.setDisabledFlags(mDisabled1, true);
4551 return true;
Jason Monk62515be2014-05-21 16:06:19 -04004552 }
4553 } catch (RemoteException e) {
Jason Monk815e0572014-08-12 17:26:36 -04004554 Log.d(TAG, "Unable to reach activity manager", e);
Jason Monk62515be2014-05-21 16:06:19 -04004555 }
Jorim Jaggi75b25972015-10-21 14:51:10 +02004556 return false;
Jason Monk62515be2014-05-21 16:06:19 -04004557 }
4558
Winson3e7e3aa2015-09-22 14:22:58 -07004559 public void updateRecentsVisibility(boolean visible) {
Winson Chung9214eff2014-06-12 13:59:25 -07004560 // Update the recents visibility flag
4561 if (visible) {
4562 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
4563 } else {
4564 mSystemUiVisibility &= ~View.RECENT_APPS_VISIBLE;
4565 }
4566 notifyUiVisibilityChanged(mSystemUiVisibility);
4567 }
John Spurlockbf370992014-06-17 13:58:31 -04004568
Jason Monk5565cb42014-09-12 10:59:21 -04004569 @Override
Andrii Kulian0f051f52016-04-14 00:41:51 -07004570 public void showScreenPinningRequest(int taskId) {
Jason Monk18f99d92014-09-11 13:36:42 -04004571 if (mKeyguardMonitor.isShowing()) {
4572 // Don't allow apps to trigger this from keyguard.
4573 return;
4574 }
4575 // Show screen pinning request, since this comes from an app, show 'no thanks', button.
Andrii Kulian0f051f52016-04-14 00:41:51 -07004576 showScreenPinningRequest(taskId, true);
Jason Monk18f99d92014-09-11 13:36:42 -04004577 }
4578
Andrii Kulian0f051f52016-04-14 00:41:51 -07004579 public void showScreenPinningRequest(int taskId, boolean allowCancel) {
4580 mScreenPinningRequest.showPrompt(taskId, allowCancel);
Jason Monk5565cb42014-09-12 10:59:21 -04004581 }
4582
Christoph Studerc8db24b2014-07-25 17:50:30 +02004583 public boolean hasActiveNotifications() {
4584 return !mNotificationData.getActiveNotifications().isEmpty();
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004585 }
4586
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01004587 public void wakeUpIfDozing(long time, MotionEvent event) {
Jorim Jaggi048af1f2014-11-11 22:51:10 +01004588 if (mDozing && mDozeScrimController.isPulsing()) {
John Spurlock8b12f222014-09-09 11:54:11 -04004589 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
Dianne Hackborn280a64e2015-07-13 14:48:08 -07004590 pm.wakeUp(time, "com.android.systemui:NODOZE");
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004591 mWakeUpComingFromTouch = true;
4592 mWakeUpTouchLocation = new PointF(event.getX(), event.getY());
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01004593 mNotificationPanel.setTouchDisabled(false);
Jorim Jaggi0d210f62015-07-10 14:24:44 -07004594 mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004595 mFalsingManager.onScreenOnFromTouch();
John Spurlock8b12f222014-09-09 11:54:11 -04004596 }
4597 }
4598
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004599 @Override
4600 public void appTransitionPending() {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004601
4602 // Use own timings when Keyguard is going away, see keyguardGoingAway and
4603 // setKeyguardFadingAway
4604 if (!mKeyguardFadingAway) {
4605 mIconController.appTransitionPending();
4606 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004607 }
4608
4609 @Override
4610 public void appTransitionCancelled() {
4611 mIconController.appTransitionCancelled();
Jorim Jaggi2adba072016-03-03 13:43:39 +01004612 EventBus.getDefault().send(new AppTransitionFinishedEvent());
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004613 }
4614
4615 @Override
4616 public void appTransitionStarting(long startTime, long duration) {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004617
4618 // Use own timings when Keyguard is going away, see keyguardGoingAway and
Adrian Roos46df1ca2015-09-11 12:38:43 -07004619 // setKeyguardFadingAway.
4620 if (!mKeyguardGoingAway) {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004621 mIconController.appTransitionStarting(startTime, duration);
4622 }
Kenny Guy3094d4a2015-04-01 19:14:10 +01004623 if (mIconPolicy != null) {
4624 mIconPolicy.appTransitionStarting(startTime, duration);
4625 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004626 }
4627
Selim Cinek372d1bd2015-08-14 13:19:37 -07004628 @Override
Jorim Jaggi2adba072016-03-03 13:43:39 +01004629 public void appTransitionFinished() {
4630 EventBus.getDefault().send(new AppTransitionFinishedEvent());
4631 }
4632
4633 @Override
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004634 public void onCameraLaunchGestureDetected(int source) {
4635 mLastCameraLaunchSource = source;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004636 if (mStartedGoingToSleep) {
4637 mLaunchCameraOnFinishedGoingToSleep = true;
4638 return;
4639 }
Zhentao Sun04f97402015-08-26 17:37:30 -07004640 if (!mNotificationPanel.canCameraGestureBeLaunched(
4641 mStatusBarKeyguardViewManager.isShowing() && mExpandedVisible)) {
Selim Cinek372d1bd2015-08-14 13:19:37 -07004642 return;
4643 }
4644 if (!mDeviceInteractive) {
4645 PowerManager pm = mContext.getSystemService(PowerManager.class);
4646 pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:CAMERA_GESTURE");
4647 mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
4648 }
Selim Cinek69ff8af2015-08-25 19:03:48 -07004649 vibrateForCameraGesture();
Selim Cinek372d1bd2015-08-14 13:19:37 -07004650 if (!mStatusBarKeyguardViewManager.isShowing()) {
4651 startActivity(KeyguardBottomAreaView.INSECURE_CAMERA_INTENT,
4652 true /* dismissShade */);
4653 } else {
4654 if (!mDeviceInteractive) {
4655 // Avoid flickering of the scrim when we instant launch the camera and the bouncer
4656 // comes on.
4657 mScrimController.dontAnimateBouncerChangesUntilNextFrame();
4658 mGestureWakeLock.acquire(LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
4659 }
Selim Cinek1b6f8192015-09-03 16:01:53 -07004660 if (mScreenTurningOn || mStatusBarKeyguardViewManager.isScreenTurnedOn()) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004661 mNotificationPanel.launchCamera(mDeviceInteractive /* animate */, source);
Selim Cinek372d1bd2015-08-14 13:19:37 -07004662 } else {
4663 // We need to defer the camera launch until the screen comes on, since otherwise
4664 // we will dismiss us too early since we are waiting on an activity to be drawn and
4665 // incorrectly get notified because of the screen on event (which resumes and pauses
4666 // some activities)
4667 mLaunchCameraOnScreenTurningOn = true;
4668 }
4669 }
4670 }
4671
Jaewan Kimc552b042016-01-18 16:08:45 +09004672 @Override
Jaewan Kimf0fd2182016-04-20 21:17:58 +09004673 public void showTvPictureInPictureMenu() {
Jaewan Kimc552b042016-01-18 16:08:45 +09004674 // no-op.
4675 }
4676
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004677 public void notifyFpAuthModeChanged() {
4678 updateDozing();
4679 }
4680
Jorim Jaggi83969702015-06-05 14:59:24 -07004681 private void updateDozing() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004682 // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
4683 mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD
4684 || mFingerprintUnlockController.getMode()
4685 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
Jorim Jaggi83969702015-06-05 14:59:24 -07004686 updateDozingState();
4687 }
4688
John Spurlockbf370992014-06-17 13:58:31 -04004689 private final class ShadeUpdates {
4690 private final ArraySet<String> mVisibleNotifications = new ArraySet<String>();
4691 private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>();
4692
4693 public void check() {
4694 mNewVisibleNotifications.clear();
Christoph Studerc8db24b2014-07-25 17:50:30 +02004695 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
4696 for (int i = 0; i < activeNotifications.size(); i++) {
4697 final Entry entry = activeNotifications.get(i);
John Spurlockbf370992014-06-17 13:58:31 -04004698 final boolean visible = entry.row != null
4699 && entry.row.getVisibility() == View.VISIBLE;
4700 if (visible) {
4701 mNewVisibleNotifications.add(entry.key + entry.notification.getPostTime());
4702 }
4703 }
4704 final boolean updates = !mVisibleNotifications.containsAll(mNewVisibleNotifications);
4705 mVisibleNotifications.clear();
Dianne Hackborn497175b2014-07-01 12:56:08 -07004706 mVisibleNotifications.addAll(mNewVisibleNotifications);
John Spurlockbf370992014-06-17 13:58:31 -04004707
4708 // We have new notifications
4709 if (updates && mDozeServiceHost != null) {
4710 mDozeServiceHost.fireNewNotifications();
4711 }
4712 }
4713 }
4714
Jorim Jaggi007f0e82015-08-14 13:56:01 -07004715 private final class DozeServiceHost extends KeyguardUpdateMonitorCallback implements DozeHost {
John Spurlockbf370992014-06-17 13:58:31 -04004716 // Amount of time to allow to update the time shown on the screen before releasing
4717 // the wakelock. This timeout is design to compensate for the fact that we don't
4718 // currently have a way to know when time display contents have actually been
4719 // refreshed once we've finished rendering a new frame.
4720 private static final long PROCESSING_TIME = 500;
4721
4722 private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
4723 private final H mHandler = new H();
4724
Christoph Studer1f32c652014-11-26 15:32:20 +01004725 // Keeps the last reported state by fireNotificationLight.
4726 private boolean mNotificationLightOn;
4727
John Spurlockc6eed842014-08-25 12:19:41 -04004728 @Override
4729 public String toString() {
Jeff Brown4d69e222014-09-18 15:27:50 -07004730 return "PSB.DozeServiceHost[mCallbacks=" + mCallbacks.size() + "]";
John Spurlock8b12f222014-09-09 11:54:11 -04004731 }
4732
John Spurlockd96179e2014-08-21 16:43:45 -04004733 public void firePowerSaveChanged(boolean active) {
4734 for (Callback callback : mCallbacks) {
4735 callback.onPowerSaveChanged(active);
4736 }
4737 }
4738
John Spurlockcad57682014-07-26 17:09:56 -04004739 public void fireBuzzBeepBlinked() {
4740 for (Callback callback : mCallbacks) {
4741 callback.onBuzzBeepBlinked();
4742 }
4743 }
4744
John Spurlockcb566aa2014-08-03 22:58:28 -04004745 public void fireNotificationLight(boolean on) {
Christoph Studer1f32c652014-11-26 15:32:20 +01004746 mNotificationLightOn = on;
John Spurlockcb566aa2014-08-03 22:58:28 -04004747 for (Callback callback : mCallbacks) {
4748 callback.onNotificationLight(on);
4749 }
4750 }
4751
John Spurlockbf370992014-06-17 13:58:31 -04004752 public void fireNewNotifications() {
4753 for (Callback callback : mCallbacks) {
4754 callback.onNewNotifications();
4755 }
4756 }
4757
4758 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004759 public void addCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04004760 mCallbacks.add(callback);
4761 }
4762
4763 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004764 public void removeCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04004765 mCallbacks.remove(callback);
4766 }
4767
4768 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004769 public void startDozing(@NonNull Runnable ready) {
4770 mHandler.obtainMessage(H.MSG_START_DOZING, ready).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04004771 }
4772
4773 @Override
John Spurlockeab28e62014-11-29 11:33:49 -05004774 public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
4775 mHandler.obtainMessage(H.MSG_PULSE_WHILE_DOZING, reason, 0, callback).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04004776 }
4777
4778 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004779 public void stopDozing() {
4780 mHandler.obtainMessage(H.MSG_STOP_DOZING).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04004781 }
4782
John Spurlockd96179e2014-08-21 16:43:45 -04004783 @Override
4784 public boolean isPowerSaveActive() {
4785 return mBatteryController != null && mBatteryController.isPowerSave();
4786 }
4787
Christoph Studer1f32c652014-11-26 15:32:20 +01004788 @Override
Jorim Jaggi007f0e82015-08-14 13:56:01 -07004789 public boolean isPulsingBlocked() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004790 return mFingerprintUnlockController.getMode()
4791 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
Jorim Jaggi007f0e82015-08-14 13:56:01 -07004792 }
4793
4794 @Override
Christoph Studer1f32c652014-11-26 15:32:20 +01004795 public boolean isNotificationLightOn() {
4796 return mNotificationLightOn;
4797 }
4798
Jeff Brown4d69e222014-09-18 15:27:50 -07004799 private void handleStartDozing(@NonNull Runnable ready) {
Jorim Jaggi83969702015-06-05 14:59:24 -07004800 if (!mDozingRequested) {
4801 mDozingRequested = true;
John Spurlock813552c2014-09-19 08:30:21 -04004802 DozeLog.traceDozing(mContext, mDozing);
Jorim Jaggi83969702015-06-05 14:59:24 -07004803 updateDozing();
John Spurlockbf370992014-06-17 13:58:31 -04004804 }
Jeff Brown4d69e222014-09-18 15:27:50 -07004805 ready.run();
John Spurlockbf370992014-06-17 13:58:31 -04004806 }
4807
John Spurlockeab28e62014-11-29 11:33:49 -05004808 private void handlePulseWhileDozing(@NonNull PulseCallback callback, int reason) {
Selim Cinekcd5b22f2016-03-08 16:15:41 -08004809 mDozeScrimController.pulse(new PulseCallback() {
4810
4811 @Override
4812 public void onPulseStarted() {
4813 callback.onPulseStarted();
4814 mStackScroller.setPulsing(true);
4815 }
4816
4817 @Override
4818 public void onPulseFinished() {
4819 callback.onPulseFinished();
4820 mStackScroller.setPulsing(false);
4821 }
4822 }, reason);
John Spurlockbf370992014-06-17 13:58:31 -04004823 }
4824
Jeff Brown4d69e222014-09-18 15:27:50 -07004825 private void handleStopDozing() {
Jorim Jaggi83969702015-06-05 14:59:24 -07004826 if (mDozingRequested) {
4827 mDozingRequested = false;
John Spurlock813552c2014-09-19 08:30:21 -04004828 DozeLog.traceDozing(mContext, mDozing);
Jorim Jaggi83969702015-06-05 14:59:24 -07004829 updateDozing();
John Spurlockbf370992014-06-17 13:58:31 -04004830 }
4831 }
4832
4833 private final class H extends Handler {
Jeff Brown4d69e222014-09-18 15:27:50 -07004834 private static final int MSG_START_DOZING = 1;
4835 private static final int MSG_PULSE_WHILE_DOZING = 2;
4836 private static final int MSG_STOP_DOZING = 3;
John Spurlockbf370992014-06-17 13:58:31 -04004837
4838 @Override
4839 public void handleMessage(Message msg) {
Jeff Brown4d69e222014-09-18 15:27:50 -07004840 switch (msg.what) {
4841 case MSG_START_DOZING:
4842 handleStartDozing((Runnable) msg.obj);
4843 break;
4844 case MSG_PULSE_WHILE_DOZING:
John Spurlockeab28e62014-11-29 11:33:49 -05004845 handlePulseWhileDozing((PulseCallback) msg.obj, msg.arg1);
Jeff Brown4d69e222014-09-18 15:27:50 -07004846 break;
4847 case MSG_STOP_DOZING:
4848 handleStopDozing();
4849 break;
John Spurlockbf370992014-06-17 13:58:31 -04004850 }
4851 }
4852 }
4853 }
Romain Guy648342f2012-05-25 10:44:45 -07004854}