blob: a5dad923b7761ce6936e7e56e51cb6122f581ac2 [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;
Joe Onorato808182d2010-07-09 18:52:06 -040031import android.content.Context;
32import android.content.Intent;
33import android.content.IntentFilter;
Daniel Sandler777dcde2013-09-30 10:21:45 -040034import android.content.res.Configuration;
Michael Jurka7f2668c2012-03-27 07:49:52 -070035import android.content.res.Resources;
John Spurlock919adac2012-10-02 16:41:12 -040036import android.database.ContentObserver;
Dan Sandler16128f42014-05-21 12:48:22 -040037import android.graphics.Bitmap;
Romain Guy648342f2012-05-25 10:44:45 -070038import android.graphics.Canvas;
39import android.graphics.ColorFilter;
Joe Onorato808182d2010-07-09 18:52:06 -040040import android.graphics.PixelFormat;
Daniel Sandlere680f542012-09-28 12:22:27 -040041import android.graphics.Point;
Jorim Jaggi2a5e4522014-11-24 21:45:20 +010042import android.graphics.PointF;
Romain Guy648342f2012-05-25 10:44:45 -070043import android.graphics.PorterDuff;
Selim Cineka0fad3b2014-09-19 17:20:05 +020044import android.graphics.PorterDuffXfermode;
Joe Onorato808182d2010-07-09 18:52:06 -040045import android.graphics.Rect;
Dan Sandler16128f42014-05-21 12:48:22 -040046import android.graphics.drawable.ColorDrawable;
Romain Guy648342f2012-05-25 10:44:45 -070047import android.graphics.drawable.Drawable;
Michael Jurka7f2668c2012-03-27 07:49:52 -070048import android.inputmethodservice.InputMethodService;
John Spurlock7b414672014-07-18 13:02:39 -040049import android.media.AudioAttributes;
Dan Sandler16128f42014-05-21 12:48:22 -040050import android.media.MediaMetadata;
51import android.media.session.MediaController;
52import android.media.session.MediaSession;
53import android.media.session.MediaSessionManager;
54import android.media.session.PlaybackState;
Selim Cinekbaa23272014-07-08 18:01:07 +020055import android.os.AsyncTask;
John Spurlock3c875662013-08-31 15:07:25 -040056import android.os.Bundle;
John Spurlock919adac2012-10-02 16:41:12 -040057import android.os.Handler;
Jason Monk4ae97d32014-12-17 10:14:33 -050058import android.os.HandlerThread;
Joe Onorato808182d2010-07-09 18:52:06 -040059import android.os.IBinder;
Joe Onorato808182d2010-07-09 18:52:06 -040060import android.os.Message;
John Spurlock56d007b2013-10-28 18:40:56 -040061import android.os.PowerManager;
Jason Monk4ae97d32014-12-17 10:14:33 -050062import android.os.Process;
Michael Jurka7f2668c2012-03-27 07:49:52 -070063import android.os.RemoteException;
Joe Onorato808182d2010-07-09 18:52:06 -040064import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070065import android.os.UserHandle;
Adrian Roos2b154a92014-11-17 15:18:39 +010066import android.os.UserManager;
Daniel Sandlerd3090562011-08-09 00:28:44 -040067import android.provider.Settings;
Chris Wren3ad4e3a2014-09-02 17:23:51 -040068import android.service.notification.NotificationListenerService;
Christoph Studerd0694b62014-06-04 16:36:01 +020069import android.service.notification.NotificationListenerService.RankingMap;
John Spurlockde84f0e2013-06-12 12:41:00 -040070import android.service.notification.StatusBarNotification;
Christoph Studer92b389d2014-04-01 18:44:40 +020071import android.util.ArraySet;
Daniel Sandler36412a72011-08-04 09:35:13 -040072import android.util.DisplayMetrics;
Chris Wren64161cc2012-12-17 16:49:30 -050073import android.util.EventLog;
Joe Onorato808182d2010-07-09 18:52:06 -040074import android.util.Log;
75import android.view.Display;
Jorim Jaggidf993512014-05-13 23:06:35 +020076import android.view.KeyEvent;
Jorim Jaggid4a57442014-04-10 02:45:55 +020077import android.view.LayoutInflater;
Joe Onorato808182d2010-07-09 18:52:06 -040078import android.view.MotionEvent;
79import android.view.VelocityTracker;
80import android.view.View;
Jim Millerf2a16b22011-07-06 17:32:48 -070081import android.view.ViewGroup.LayoutParams;
Dan Sandler44c0dfd2014-06-09 11:26:16 -040082import android.view.ViewStub;
Joe Onorato808182d2010-07-09 18:52:06 -040083import android.view.WindowManager;
Jorim Jaggi786afcb2014-09-25 02:41:29 +020084import android.view.WindowManagerGlobal;
Jason Monk815e0572014-08-12 17:26:36 -040085import android.view.accessibility.AccessibilityEvent;
Jorim Jaggi4e0880e2014-07-25 14:51:50 +020086import android.view.animation.AccelerateDecelerateInterpolator;
Daniel Sandlerd7e96862012-04-26 01:10:29 -040087import android.view.animation.AccelerateInterpolator;
Jorim Jaggib13d36d2014-06-06 18:03:52 +020088import android.view.animation.Interpolator;
Jorim Jaggi4e0880e2014-07-25 14:51:50 +020089import android.view.animation.LinearInterpolator;
Jorim Jaggib13d36d2014-06-06 18:03:52 +020090import android.view.animation.PathInterpolator;
Dan Sandler16128f42014-05-21 12:48:22 -040091import android.widget.ImageView;
Joe Onorato808182d2010-07-09 18:52:06 -040092import android.widget.TextView;
John Spurlock34e13d92013-08-10 06:52:28 -040093
Joe Onorato808182d2010-07-09 18:52:06 -040094import com.android.internal.statusbar.StatusBarIcon;
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +010095import com.android.keyguard.KeyguardHostView.OnDismissAction;
Jorim Jaggi03c701e2014-04-02 12:39:51 +020096import com.android.keyguard.ViewMediatorCallback;
Jorim Jaggi708f7722014-08-20 17:30:38 +020097import com.android.systemui.BatteryMeterView;
John Spurlock3c875662013-08-31 15:07:25 -040098import com.android.systemui.DemoMode;
Christoph Studerb0183992014-12-22 21:02:26 +010099import com.android.systemui.EventLogConstants;
Chris Wren64161cc2012-12-17 16:49:30 -0500100import com.android.systemui.EventLogTags;
Andrew Flynn82862572015-04-01 14:22:37 -0400101import com.android.systemui.Prefs;
Joe Onorato808182d2010-07-09 18:52:06 -0400102import com.android.systemui.R;
Selim Cinekaac93252015-04-14 20:04:12 -0700103import com.android.systemui.assist.AssistGestureManager;
Jeff Brown4d69e222014-09-18 15:27:50 -0700104import com.android.systemui.doze.DozeHost;
John Spurlock813552c2014-09-19 08:30:21 -0400105import com.android.systemui.doze.DozeLog;
Jorim Jaggicff0acb2014-03-31 16:35:15 +0200106import com.android.systemui.keyguard.KeyguardViewMediator;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400107import com.android.systemui.qs.QSPanel;
Jorim Jaggid61f2272014-12-19 20:35:35 +0100108import com.android.systemui.recents.ScreenPinningRequest;
Selim Cineka32ab602014-06-11 15:06:01 +0200109import com.android.systemui.statusbar.ActivatableNotificationView;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200110import com.android.systemui.statusbar.BackDropView;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500111import com.android.systemui.statusbar.BaseStatusBar;
Michael Jurkaa600fd92012-06-25 15:57:05 -0700112import com.android.systemui.statusbar.CommandQueue;
Dan Sandlereceda3d2014-07-21 15:35:01 -0400113import com.android.systemui.statusbar.DismissView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200114import com.android.systemui.statusbar.DragDownHelper;
Jorim Jaggia2052ea2014-08-05 16:22:30 +0200115import com.android.systemui.statusbar.EmptyShadeView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200116import com.android.systemui.statusbar.ExpandableNotificationRow;
Daniel Sandler33805342012-07-23 15:45:12 -0400117import com.android.systemui.statusbar.GestureRecorder;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200118import com.android.systemui.statusbar.KeyguardIndicationController;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700119import com.android.systemui.statusbar.NotificationData;
Daniel Sandler58b173b2012-05-03 11:25:29 -0400120import com.android.systemui.statusbar.NotificationData.Entry;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200121import com.android.systemui.statusbar.NotificationOverflowContainer;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200122import com.android.systemui.statusbar.ScrimView;
Christian Robertson2e347422011-08-11 14:01:04 -0700123import com.android.systemui.statusbar.SignalClusterView;
Selim Cinekc27437b2014-05-14 10:23:33 +0200124import com.android.systemui.statusbar.SpeedBumpView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200125import com.android.systemui.statusbar.StatusBarState;
Christoph Studer2231c6e2014-12-19 12:40:13 +0100126import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200127import com.android.systemui.statusbar.policy.AccessibilityController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400128import com.android.systemui.statusbar.policy.BatteryController;
John Spurlock0ff62e02014-07-22 16:15:08 -0400129import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400130import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200131import com.android.systemui.statusbar.policy.BrightnessMirrorController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400132import com.android.systemui.statusbar.policy.CastControllerImpl;
Adrian Roosb83777b2014-06-30 15:11:53 +0200133import com.android.systemui.statusbar.policy.FlashlightController;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700134import com.android.systemui.statusbar.policy.HeadsUpManager;
Jason Monk3d5f5512014-07-25 11:17:28 -0400135import com.android.systemui.statusbar.policy.HotspotControllerImpl;
Jason Monk815e0572014-08-12 17:26:36 -0400136import com.android.systemui.statusbar.policy.KeyButtonView;
John Spurlock657c62c2014-07-22 12:18:09 -0400137import com.android.systemui.statusbar.policy.KeyguardMonitor;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700138import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400139import com.android.systemui.statusbar.policy.LocationControllerImpl;
140import com.android.systemui.statusbar.policy.NetworkControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400141import com.android.systemui.statusbar.policy.NextAlarmController;
Jorim Jaggi85dc23c2014-09-08 14:42:29 +0200142import com.android.systemui.statusbar.policy.PreviewInflater;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400143import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400144import com.android.systemui.statusbar.policy.SecurityControllerImpl;
145import com.android.systemui.statusbar.policy.UserInfoController;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200146import com.android.systemui.statusbar.policy.UserSwitcherController;
John Spurlock86005342014-05-23 11:58:00 -0400147import com.android.systemui.statusbar.policy.ZenModeController;
Selim Cinek67b22602014-03-10 15:40:16 +0100148import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
Christoph Studer92b389d2014-04-01 18:44:40 +0200149import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
Selim Cinekb036ca42015-02-20 15:56:28 +0100150import com.android.systemui.statusbar.stack.StackViewState;
John Spurlock86005342014-05-23 11:58:00 -0400151import com.android.systemui.volume.VolumeComponent;
Selim Cinek67b22602014-03-10 15:40:16 +0100152
Daniel Sandler6a858c32012-03-12 14:38:58 -0400153import java.io.FileDescriptor;
154import java.io.PrintWriter;
155import java.util.ArrayList;
Christoph Studer92b389d2014-04-01 18:44:40 +0200156import java.util.Collection;
157import java.util.Collections;
Selim Cinekb5605e52015-02-20 18:21:41 +0100158import java.util.HashMap;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700159import java.util.HashSet;
Dan Sandler16128f42014-05-21 12:48:22 -0400160import java.util.List;
John Spurlock7bbb9f62014-10-21 12:15:28 -0400161import java.util.Map;
Selim Cineka59ecc32015-04-07 10:51:49 -0700162import java.util.TreeSet;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700163
164import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
165import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
166import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
167import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
168import static android.app.StatusBarManager.windowStateToString;
169import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
170import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
171import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
172import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
173import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
174import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
175import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
Daniel Sandler6a858c32012-03-12 14:38:58 -0400176
Jorim Jaggiecbab362014-04-23 16:13:15 +0200177public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Selim Cinek8d490d42015-04-10 00:05:50 -0700178 DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
179 HeadsUpManager.OnHeadsUpChangedListener {
Joe Onoratofd52b182010-11-10 18:00:52 -0800180 static final String TAG = "PhoneStatusBar";
Daniel Sandler198a0302012-08-17 16:04:31 -0400181 public static final boolean DEBUG = BaseStatusBar.DEBUG;
Chris Wren6d15a362013-08-20 18:46:29 -0400182 public static final boolean SPEW = false;
Daniel Sandler7579bca2011-08-18 15:47:26 -0400183 public static final boolean DUMPTRUCK = true; // extra dumpsys info
Daniel Sandlerfa027f52013-04-11 22:01:47 -0400184 public static final boolean DEBUG_GESTURES = false;
Dan Sandler16128f42014-05-21 12:48:22 -0400185 public static final boolean DEBUG_MEDIA = false;
186 public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
Joe Onorato808182d2010-07-09 18:52:06 -0400187
John Spurlock342cad72013-10-08 09:36:50 -0400188 public static final boolean DEBUG_WINDOW_STATE = false;
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400189
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400190 // additional instrumentation for testing purposes; intended to be left on during development
Daniel Sandler7c351742011-10-17 10:48:06 -0400191 public static final boolean CHATTY = DEBUG;
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400192
Dan Sandler16128f42014-05-21 12:48:22 -0400193 public static final boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
194
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400195 private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
Daniel Sandler11cf1782012-09-27 14:03:08 -0400196 private static final int MSG_CLOSE_PANELS = 1001;
197 private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
Jorim Jaggi826730a2014-12-08 21:05:13 +0100198 private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
Winson Chungb1f74992014-08-08 12:53:09 -0700199 // 1020-1040 reserved for BaseStatusBar
Joe Onorato808182d2010-07-09 18:52:06 -0400200
Jorim Jaggi826730a2014-12-08 21:05:13 +0100201 // Time after we abort the launch transition.
202 private static final long LAUNCH_TRANSITION_TIMEOUT_MS = 5000;
203
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400204 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
205
John Spurlocke1f366f2013-08-05 12:22:40 -0400206 private static final int STATUS_OR_NAV_TRANSIENT =
207 View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
John Spurlock32beb2c2013-03-11 10:16:47 -0400208 private static final long AUTOHIDE_TIMEOUT_MS = 3000;
John Spurlocke1f366f2013-08-05 12:22:40 -0400209
Christoph Studer92b389d2014-04-01 18:44:40 +0200210 /** The minimum delay in ms between reports of notification visibility. */
211 private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
212
Jorim Jaggi93a2bb22014-06-02 19:57:28 +0200213 /**
214 * The delay to reset the hint text when the hint animation is finished running.
215 */
216 private static final int HINT_RESET_DELAY_MS = 1200;
217
John Spurlock7b414672014-07-18 13:02:39 -0400218 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
219 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
220 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
221 .build();
222
Selim Cinekbaa23272014-07-08 18:01:07 +0200223 public static final int FADE_KEYGUARD_START_DELAY = 100;
224 public static final int FADE_KEYGUARD_DURATION = 300;
225
Jason Monk815e0572014-08-12 17:26:36 -0400226 /** Allow some time inbetween the long press for back and recents. */
227 private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
228
Joe Onoratofd52b182010-11-10 18:00:52 -0800229 PhoneStatusBarPolicy mIconPolicy;
Joe Onorato808182d2010-07-09 18:52:06 -0400230
Daniel Sandler2b697352011-07-22 16:23:09 -0400231 // These are no longer handled by the policy, because we need custom strategies for them
John Spurlockaf8d6c42014-05-07 17:49:08 -0400232 BluetoothControllerImpl mBluetoothController;
Jason Monk3d5f5512014-07-25 11:17:28 -0400233 SecurityControllerImpl mSecurityController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400234 BatteryController mBatteryController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400235 LocationControllerImpl mLocationController;
236 NetworkControllerImpl mNetworkController;
Jason Monk51e4dc02014-07-22 12:00:47 -0400237 HotspotControllerImpl mHotspotController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400238 RotationLockControllerImpl mRotationLockController;
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200239 UserInfoController mUserInfoController;
John Spurlock86005342014-05-23 11:58:00 -0400240 ZenModeController mZenModeController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400241 CastControllerImpl mCastController;
John Spurlock86005342014-05-23 11:58:00 -0400242 VolumeComponent mVolumeComponent;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700243 KeyguardUserSwitcher mKeyguardUserSwitcher;
Adrian Roosb83777b2014-06-30 15:11:53 +0200244 FlashlightController mFlashlightController;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200245 UserSwitcherController mUserSwitcherController;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200246 NextAlarmController mNextAlarmController;
John Spurlock657c62c2014-07-22 12:18:09 -0400247 KeyguardMonitor mKeyguardMonitor;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200248 BrightnessMirrorController mBrightnessMirrorController;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200249 AccessibilityController mAccessibilityController;
Jim Miller5e6af442011-12-02 18:24:26 -0800250
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400251 int mNaturalBarHeight = -1;
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100252
Joe Onorato808182d2010-07-09 18:52:06 -0400253 Display mDisplay;
Daniel Sandlere680f542012-09-28 12:22:27 -0400254 Point mCurrentDisplaySize = new Point();
Joe Onorato808182d2010-07-09 18:52:06 -0400255
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400256 StatusBarWindowView mStatusBarWindow;
Joe Onoratofd52b182010-11-10 18:00:52 -0800257 PhoneStatusBarView mStatusBarView;
John Spurlockd4e65752013-08-28 14:17:09 -0400258 private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100259 private StatusBarWindowManager mStatusBarWindowManager;
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200260 private UnlockMethodCache mUnlockMethodCache;
John Spurlockbf370992014-06-17 13:58:31 -0400261 private DozeServiceHost mDozeServiceHost;
Selim Cinek29ed3c92014-09-23 20:44:35 +0200262 private boolean mScreenOnComingFromTouch;
Jorim Jaggi2a5e4522014-11-24 21:45:20 +0100263 private PointF mScreenOnTouchLocation;
Daniel Sandlera310af82012-04-24 01:20:13 -0400264
Joe Onorato808182d2010-07-09 18:52:06 -0400265 int mPixelFormat;
Joe Onorato808182d2010-07-09 18:52:06 -0400266 Object mQueueLock = new Object();
267
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100268 StatusBarIconController mIconController;
Joe Onorato808182d2010-07-09 18:52:06 -0400269
270 // expanded notifications
Daniel Sandler040c2e42012-10-17 00:56:33 -0400271 NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
Joe Onorato808182d2010-07-09 18:52:06 -0400272 View mExpandedContents;
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400273 TextView mNotificationPanelDebugText;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400274
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400275 // settings
John Spurlockaf8d6c42014-05-07 17:49:08 -0400276 private QSPanel mQSPanel;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400277
Joe Onorato808182d2010-07-09 18:52:06 -0400278 // top bar
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200279 StatusBarHeaderView mHeader;
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200280 KeyguardStatusBarView mKeyguardStatusBar;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200281 View mKeyguardStatusView;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200282 KeyguardBottomAreaView mKeyguardBottomArea;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200283 boolean mLeaveOpenOnKeyguardHide;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200284 KeyguardIndicationController mKeyguardIndicationController;
Jorim Jaggie70d31f2014-04-24 22:08:30 +0200285
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700286 private boolean mKeyguardFadingAway;
287 private long mKeyguardFadingAwayDelay;
288 private long mKeyguardFadingAwayDuration;
289
Jorim Jaggid4a57442014-04-10 02:45:55 +0200290 int mKeyguardMaxNotificationCount;
Daniel Sandlerd3090562011-08-09 00:28:44 -0400291
Joe Onorato808182d2010-07-09 18:52:06 -0400292 boolean mExpandedVisible;
293
John Spurlockd4e65752013-08-28 14:17:09 -0400294 private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400295
Joe Onorato808182d2010-07-09 18:52:06 -0400296 // the tracker view
Joe Onorato808182d2010-07-09 18:52:06 -0400297 int mTrackingPosition; // the position of the top of the tracking view.
Joe Onorato808182d2010-07-09 18:52:06 -0400298
Joe Onorato808182d2010-07-09 18:52:06 -0400299 // Tracking finger for opening/closing.
300 int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
301 boolean mTracking;
302 VelocityTracker mVelocityTracker;
303
Joe Onorato808182d2010-07-09 18:52:06 -0400304 int[] mAbsPos = new int[2];
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200305 ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
Chet Haase2f2022a2011-10-11 06:41:59 -0700306
Joe Onorato808182d2010-07-09 18:52:06 -0400307 // for disabling the status bar
308 int mDisabled = 0;
309
Daniel Sandler60ee2562011-07-22 12:34:33 -0400310 // tracking calls to View.setSystemUiVisibility()
311 int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
312
Daniel Sandler36412a72011-08-04 09:35:13 -0400313 DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700314
Daniel Sandler33805342012-07-23 15:45:12 -0400315 // XXX: gesture research
Daniel Sandler151f00d2012-10-02 22:33:08 -0400316 private final GestureRecorder mGestureRec = DEBUG_GESTURES
John Spurlock209bede2013-07-17 12:23:27 -0400317 ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
Daniel Sandler151f00d2012-10-02 22:33:08 -0400318 : null;
Daniel Sandler33805342012-07-23 15:45:12 -0400319
Jason Monk18f99d92014-09-11 13:36:42 -0400320 private ScreenPinningRequest mScreenPinningRequest;
321
Daniel Sandler328310c2011-09-23 15:56:52 -0400322 private int mNavigationIconHints = 0;
Jason Monk4ae97d32014-12-17 10:14:33 -0500323 private HandlerThread mHandlerThread;
Daniel Sandler328310c2011-09-23 15:56:52 -0400324
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700325 private AssistGestureManager mAssistGestureManager;
326
John Spurlock919adac2012-10-02 16:41:12 -0400327 // ensure quick settings is disabled until the current user makes it through the setup wizard
328 private boolean mUserSetup = false;
329 private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
330 @Override
331 public void onChange(boolean selfChange) {
332 final boolean userSetup = 0 != Settings.Secure.getIntForUser(
333 mContext.getContentResolver(),
334 Settings.Secure.USER_SETUP_COMPLETE,
335 0 /*default */,
336 mCurrentUserId);
John Spurlockcd686b52013-06-05 10:13:46 -0400337 if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
John Spurlocke4e8c562012-10-04 09:55:01 -0400338 "selfChange=%s userSetup=%s mUserSetup=%s",
339 selfChange, userSetup, mUserSetup));
John Spurlock73203eb2014-04-15 16:14:46 -0400340
John Spurlock919adac2012-10-02 16:41:12 -0400341 if (userSetup != mUserSetup) {
342 mUserSetup = userSetup;
John Spurlock919adac2012-10-02 16:41:12 -0400343 if (!mUserSetup && mStatusBarView != null)
344 animateCollapseQuickSettings();
345 }
346 }
347 };
348
Chris Wrenf6e83f42013-09-11 14:02:59 -0400349 final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
350 @Override
351 public void onChange(boolean selfChange) {
352 boolean wasUsing = mUseHeadsUp;
Jason Monkf7019542014-07-31 12:42:25 -0400353 mUseHeadsUp = ENABLE_HEADS_UP && !mDisableNotificationAlerts
354 && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
Chris Wren10d82df2014-03-01 10:34:51 -0500355 mContext.getContentResolver(), Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Chris Wren7bd241232014-02-28 16:25:05 -0500356 Settings.Global.HEADS_UP_OFF);
Chris Wren22ae46e2014-02-26 18:08:09 -0500357 mHeadsUpTicker = mUseHeadsUp && 0 != Settings.Global.getInt(
358 mContext.getContentResolver(), SETTING_HEADS_UP_TICKER, 0);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400359 Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
360 if (wasUsing != mUseHeadsUp) {
361 if (!mUseHeadsUp) {
362 Log.d(TAG, "dismissing any existing heads up notification on disable event");
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700363 mHeadsUpManager.releaseAllImmediately();
Chris Wrenf6e83f42013-09-11 14:02:59 -0400364 }
365 }
366 }
367 };
368
John Spurlockcfc359a2013-09-05 10:42:03 -0400369 private int mInteractingWindows;
John Spurlock32beb2c2013-03-11 10:16:47 -0400370 private boolean mAutohideSuspended;
John Spurlockd4e65752013-08-28 14:17:09 -0400371 private int mStatusBarMode;
372 private int mNavigationBarMode;
Jorim Jaggid41083a2014-09-12 02:54:40 +0200373
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200374 private ViewMediatorCallback mKeyguardViewMediatorCallback;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200375 private ScrimController mScrimController;
Jorim Jaggi048af1f2014-11-11 22:51:10 +0100376 private DozeScrimController mDozeScrimController;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200377
John Spurlock32beb2c2013-03-11 10:16:47 -0400378 private final Runnable mAutohide = new Runnable() {
379 @Override
380 public void run() {
John Spurlocke1f366f2013-08-05 12:22:40 -0400381 int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT;
John Spurlock9deaa282013-07-25 13:03:47 -0400382 if (mSystemUiVisibility != requested) {
383 notifyUiVisibilityChanged(requested);
384 }
John Spurlock32beb2c2013-03-11 10:16:47 -0400385 }};
386
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700387 private boolean mWaitingForKeyguardExit;
John Spurlockbf370992014-06-17 13:58:31 -0400388 private boolean mDozing;
Jorim Jaggi0e664392014-09-27 01:30:22 +0200389 private boolean mScrimSrcModeEnabled;
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100390
Jorim Jaggi4e0880e2014-07-25 14:51:50 +0200391 private Interpolator mLinearInterpolator = new LinearInterpolator();
392 private Interpolator mBackdropInterpolator = new AccelerateDecelerateInterpolator();
Jorim Jaggi61d37f62014-07-30 17:26:55 +0200393 public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
394 public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200395
Selim Cineka0fad3b2014-09-19 17:20:05 +0200396 private BackDropView mBackdrop;
Dan Sandler16128f42014-05-21 12:48:22 -0400397 private ImageView mBackdropFront, mBackdropBack;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200398 private PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
399 private PorterDuffXfermode mSrcOverXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);
Dan Sandler16128f42014-05-21 12:48:22 -0400400
401 private MediaSessionManager mMediaSessionManager;
402 private MediaController mMediaController;
403 private String mMediaNotificationKey;
404 private MediaMetadata mMediaMetadata;
405 private MediaController.Callback mMediaListener
406 = new MediaController.Callback() {
407 @Override
408 public void onPlaybackStateChanged(PlaybackState state) {
409 super.onPlaybackStateChanged(state);
410 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onPlaybackStateChanged: " + state);
411 }
412
413 @Override
414 public void onMetadataChanged(MediaMetadata metadata) {
415 super.onMetadataChanged(metadata);
416 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onMetadataChanged: " + metadata);
417 mMediaMetadata = metadata;
418 updateMediaMetaData(true);
419 }
420 };
421
422 private final OnChildLocationsChangedListener mOnChildLocationsChangedListener =
423 new OnChildLocationsChangedListener() {
424 @Override
425 public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout) {
426 userActivity();
427 }
428 };
429
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200430 private int mDisabledUnmodified;
431
Christoph Studer92b389d2014-04-01 18:44:40 +0200432 /** Keys of notifications currently visible to the user. */
433 private final ArraySet<String> mCurrentlyVisibleNotifications = new ArraySet<String>();
434 private long mLastVisibilityReportUptimeMs;
435
John Spurlockbf370992014-06-17 13:58:31 -0400436 private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
437
Jorim Jaggi362dd6d2014-07-09 19:04:07 +0200438 private int mDrawCount;
Selim Cinekbaa23272014-07-08 18:01:07 +0200439 private Runnable mLaunchTransitionEndRunnable;
440 private boolean mLaunchTransitionFadingAway;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +0200441 private ExpandableNotificationRow mDraggedDownRow;
Jorim Jaggi362dd6d2014-07-09 19:04:07 +0200442
Christoph Studer2231c6e2014-12-19 12:40:13 +0100443 // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
444 private int mLastLoggedStateFingerprint;
445
Selim Cinekb036ca42015-02-20 15:56:28 +0100446 private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_CARD
447 | StackViewState.LOCATION_TOP_STACK_PEEKING
448 | StackViewState.LOCATION_MAIN_AREA
449 | StackViewState.LOCATION_BOTTOM_STACK_PEEKING;
Christoph Studer92b389d2014-04-01 18:44:40 +0200450
451 private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
452 new OnChildLocationsChangedListener() {
453 @Override
454 public void onChildLocationsChanged(
455 NotificationStackScrollLayout stackScrollLayout) {
456 if (mHandler.hasCallbacks(mVisibilityReporter)) {
457 // Visibilities will be reported when the existing
458 // callback is executed.
459 return;
460 }
461 // Calculate when we're allowed to run the visibility
462 // reporter. Note that this timestamp might already have
463 // passed. That's OK, the callback will just be executed
464 // ASAP.
465 long nextReportUptimeMs =
466 mLastVisibilityReportUptimeMs + VISIBILITY_REPORT_MIN_DELAY_MS;
467 mHandler.postAtTime(mVisibilityReporter, nextReportUptimeMs);
468 }
469 };
470
471 // Tracks notifications currently visible in mNotificationStackScroller and
472 // emits visibility events via NoMan on changes.
473 private final Runnable mVisibilityReporter = new Runnable() {
474 private final ArrayList<String> mTmpNewlyVisibleNotifications = new ArrayList<String>();
475 private final ArrayList<String> mTmpCurrentlyVisibleNotifications = new ArrayList<String>();
476
477 @Override
478 public void run() {
479 mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
480
481 // 1. Loop over mNotificationData entries:
482 // A. Keep list of visible notifications.
483 // B. Keep list of previously hidden, now visible notifications.
484 // 2. Compute no-longer visible notifications by removing currently
485 // visible notifications from the set of previously visible
486 // notifications.
487 // 3. Report newly visible and no-longer visible notifications.
488 // 4. Keep currently visible notifications for next report.
Christoph Studerc8db24b2014-07-25 17:50:30 +0200489 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
490 int N = activeNotifications.size();
Christoph Studer92b389d2014-04-01 18:44:40 +0200491 for (int i = 0; i < N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +0200492 Entry entry = activeNotifications.get(i);
Christoph Studer92b389d2014-04-01 18:44:40 +0200493 String key = entry.notification.getKey();
494 boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(key);
495 boolean currentlyVisible =
496 (mStackScroller.getChildLocation(entry.row) & VISIBLE_LOCATIONS) != 0;
497 if (currentlyVisible) {
498 // Build new set of visible notifications.
499 mTmpCurrentlyVisibleNotifications.add(key);
500 }
501 if (!previouslyVisible && currentlyVisible) {
502 mTmpNewlyVisibleNotifications.add(key);
503 }
504 }
505 ArraySet<String> noLongerVisibleNotifications = mCurrentlyVisibleNotifications;
506 noLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications);
507
508 logNotificationVisibilityChanges(
509 mTmpNewlyVisibleNotifications, noLongerVisibleNotifications);
510
511 mCurrentlyVisibleNotifications.clear();
512 mCurrentlyVisibleNotifications.addAll(mTmpCurrentlyVisibleNotifications);
513
514 mTmpNewlyVisibleNotifications.clear();
515 mTmpCurrentlyVisibleNotifications.clear();
516 }
517 };
518
Jorim Jaggiecbab362014-04-23 16:13:15 +0200519 private final View.OnClickListener mOverflowClickListener = new View.OnClickListener() {
520 @Override
521 public void onClick(View v) {
522 goToLockedShade(null);
523 }
524 };
Selim Cinekb5605e52015-02-20 18:21:41 +0100525 private HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>> mTmpChildOrderMap
526 = new HashMap<>();
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700527 private HashSet<Entry> mHeadsUpEntriesToRemoveOnSwitch = new HashSet<>();
528 private RankingMap mLatestRankingMap;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200529
Joe Onorato808182d2010-07-09 18:52:06 -0400530 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400531 public void start() {
532 mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
533 .getDefaultDisplay();
Daniel Sandler7e8ae502013-10-10 23:38:19 -0400534 updateDisplaySize();
Jorim Jaggi0e664392014-09-27 01:30:22 +0200535 mScrimSrcModeEnabled = mContext.getResources().getBoolean(
536 R.bool.config_status_bar_scrim_behind_use_src);
Adrian Roos75fa3852015-01-27 20:21:44 +0100537
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500538 super.start(); // calls createAndAddWindows()
Joe Onorato808182d2010-07-09 18:52:06 -0400539
Dan Sandler16128f42014-05-21 12:48:22 -0400540 mMediaSessionManager
541 = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
542 // TODO: use MediaSessionManager.SessionListener to hook us up to future updates
543 // in session state
544
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400545 addNavigationBar();
546
Joe Onorato808182d2010-07-09 18:52:06 -0400547 // Lastly, call to the icon policy to install/update all the icons.
Jason Monk952d5d82014-10-27 15:28:22 -0400548 mIconPolicy = new PhoneStatusBarPolicy(mContext, mCastController, mHotspotController);
John Spurlocke677d712014-02-13 12:52:19 -0500549 mSettingsObserver.onChange(false); // set up
Chris Wrenf6e83f42013-09-11 14:02:59 -0400550
551 mHeadsUpObserver.onChange(true); // set up
552 if (ENABLE_HEADS_UP) {
553 mContext.getContentResolver().registerContentObserver(
Chris Wren10d82df2014-03-01 10:34:51 -0500554 Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED), true,
Chris Wrenf6e83f42013-09-11 14:02:59 -0400555 mHeadsUpObserver);
Chris Wren22ae46e2014-02-26 18:08:09 -0500556 mContext.getContentResolver().registerContentObserver(
557 Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
558 mHeadsUpObserver);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400559 }
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200560 mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
Christoph Studer2231c6e2014-12-19 12:40:13 +0100561 mUnlockMethodCache.addListener(this);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100562 startKeyguard();
John Spurlockbf370992014-06-17 13:58:31 -0400563
564 mDozeServiceHost = new DozeServiceHost();
Jeff Brown4d69e222014-09-18 15:27:50 -0700565 putComponent(DozeHost.class, mDozeServiceHost);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200566 putComponent(PhoneStatusBar.class, this);
John Spurlock89f060a2014-07-16 21:03:15 -0400567
568 setControllerUsers();
Chris Wrencd8f4f72014-08-27 18:48:13 -0400569
570 notifyUserAboutHiddenNotifications();
Jason Monk18f99d92014-09-11 13:36:42 -0400571
572 mScreenPinningRequest = new ScreenPinningRequest(mContext);
Joe Onorato808182d2010-07-09 18:52:06 -0400573 }
574
575 // ================================================================================
576 // Constructing the view
577 // ================================================================================
Jim Millere898ac52012-04-06 17:10:57 -0700578 protected PhoneStatusBarView makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400579 final Context context = mContext;
Joe Onorato808182d2010-07-09 18:52:06 -0400580
581 Resources res = context.getResources();
582
Daniel Sandler6e8db882011-10-26 15:40:51 -0400583 updateDisplaySize(); // populates mDisplayMetrics
Jorim Jaggi2e115c52014-07-01 21:27:58 +0200584 updateResources();
Joe Onorato808182d2010-07-09 18:52:06 -0400585
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400586 mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
Daniel Sandlera310af82012-04-24 01:20:13 -0400587 R.layout.super_status_bar, null);
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400588 mStatusBarWindow.mService = this;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400589 mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
590 @Override
591 public boolean onTouch(View v, MotionEvent event) {
John Spurlock9deaa282013-07-25 13:03:47 -0400592 checkUserAutohide(v, event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400593 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandler37a38aa2013-02-13 17:15:57 -0500594 if (mExpandedVisible) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400595 animateCollapsePanels();
Daniel Sandler21b274e2012-05-02 15:07:51 -0400596 }
597 }
Chris Wren5de6e942012-05-16 14:22:21 -0400598 return mStatusBarWindow.onTouchEvent(event);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700599 }
600 });
Daniel Sandler21b274e2012-05-02 15:07:51 -0400601
Daniel Sandlera310af82012-04-24 01:20:13 -0400602 mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
Daniel Sandler08d05e32012-08-08 16:39:54 -0400603 mStatusBarView.setBar(this);
John Spurlock209bede2013-07-17 12:23:27 -0400604
Daniel Sandler08d05e32012-08-08 16:39:54 -0400605 PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
606 mStatusBarView.setPanelHolder(holder);
607
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100608 mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
609 R.id.notification_panel);
Daniel Sandler040c2e42012-10-17 00:56:33 -0400610 mNotificationPanel.setStatusBar(this);
Joe Onorato808182d2010-07-09 18:52:06 -0400611
Jeff Brown98365d72012-08-19 20:30:52 -0700612 if (!ActivityManager.isHighEndGfx()) {
Romain Guy328b3582012-05-08 15:30:57 -0700613 mStatusBarWindow.setBackground(null);
Alan Viverette4a357cd2015-03-18 18:37:18 -0700614 mNotificationPanel.setBackground(new FastColorDrawable(context.getColor(
Romain Guy648342f2012-05-25 10:44:45 -0700615 R.color.notification_panel_solid_background)));
Romain Guy328b3582012-05-08 15:30:57 -0700616 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700617
Selim Cineka59ecc32015-04-07 10:51:49 -0700618 mHeadsUpManager = new HeadsUpManager(context, mNotificationPanel.getViewTreeObserver());
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700619 mHeadsUpManager.setBar(this);
620 mHeadsUpManager.addListener(this);
621 mHeadsUpManager.addListener(mNotificationPanel);
622 mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
Selim Cinekfbe9a442015-04-13 16:09:49 -0700623 mNotificationData.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700624
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400625 if (MULTIUSER_DEBUG) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100626 mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
627 R.id.header_debug_info);
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400628 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
629 }
Joe Onorato808182d2010-07-09 18:52:06 -0400630
John Spurlockd5ef5462012-06-13 11:19:51 -0400631 updateShowSearchHoldoff();
632
Daniel Sandler0129b312011-05-11 11:54:11 -0400633 try {
Jeff Brown98365d72012-08-19 20:30:52 -0700634 boolean showNav = mWindowManagerService.hasNavigationBar();
John Spurlockcd686b52013-06-05 10:13:46 -0400635 if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
Daniel Sandler0129b312011-05-11 11:54:11 -0400636 if (showNav) {
Jim Miller5e6af442011-12-02 18:24:26 -0800637 mNavigationBarView =
Daniel Sandler0129b312011-05-11 11:54:11 -0400638 (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400639
Daniel Sandler6da2b762011-09-14 16:04:59 -0400640 mNavigationBarView.setDisabledFlags(mDisabled);
Jim Millere898ac52012-04-06 17:10:57 -0700641 mNavigationBarView.setBar(this);
Jorim Jaggif4797922014-08-04 22:49:41 +0200642 mNavigationBarView.setOnVerticalChangedListener(
643 new NavigationBarView.OnVerticalChangedListener() {
644 @Override
645 public void onVerticalChanged(boolean isVertical) {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700646 if (mAssistGestureManager != null) {
647 mAssistGestureManager.onConfigurationChanged();
Jorim Jaggif4797922014-08-04 22:49:41 +0200648 }
Jorim Jaggidd5b8862014-08-05 21:04:39 +0200649 mNotificationPanel.setQsScrimEnabled(!isVertical);
Jorim Jaggif4797922014-08-04 22:49:41 +0200650 }
651 });
John Spurlock9deaa282013-07-25 13:03:47 -0400652 mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
653 @Override
654 public boolean onTouch(View v, MotionEvent event) {
655 checkUserAutohide(v, event);
656 return false;
657 }});
Daniel Sandler0129b312011-05-11 11:54:11 -0400658 }
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400659 } catch (RemoteException ex) {
660 // no window manager? good luck with that
Daniel Sandler0129b312011-05-11 11:54:11 -0400661 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400662
Joe Onorato808182d2010-07-09 18:52:06 -0400663 // figure out which pixel-format to use for the status bar.
Daniel Sandlerf733c2a2011-09-25 15:03:40 -0400664 mPixelFormat = PixelFormat.OPAQUE;
Daniel Sandler173bae22012-09-25 14:37:42 -0400665
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100666 mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
667 R.id.notification_stack_scroller);
668 mStackScroller.setLongPressListener(getNotificationLongClicker());
Selim Cinek19c8c702014-08-25 22:09:19 +0200669 mStackScroller.setPhoneStatusBar(this);
Selim Cinekb5605e52015-02-20 18:21:41 +0100670 mStackScroller.setGroupManager(mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700671 mStackScroller.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb5605e52015-02-20 18:21:41 +0100672 mGroupManager.setOnGroupChangeListener(mStackScroller);
Selim Cinek80a14e52014-03-27 16:58:04 +0100673
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200674 mKeyguardIconOverflowContainer =
675 (NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
676 R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
677 mKeyguardIconOverflowContainer.setOnActivatedListener(this);
Jorim Jaggie96fcd12014-05-07 21:10:35 +0200678 mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
Jorim Jaggid4a57442014-04-10 02:45:55 +0200679 mStackScroller.addView(mKeyguardIconOverflowContainer);
680
Selim Cinekc27437b2014-05-14 10:23:33 +0200681 SpeedBumpView speedBump = (SpeedBumpView) LayoutInflater.from(mContext).inflate(
682 R.layout.status_bar_notification_speed_bump, mStackScroller, false);
683 mStackScroller.setSpeedBumpView(speedBump);
Selim Cinekbecf5e32014-08-12 14:29:18 +0200684 mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
685 R.layout.status_bar_no_notifications, mStackScroller, false);
686 mStackScroller.setEmptyShadeView(mEmptyShadeView);
Dan Sandlereceda3d2014-07-21 15:35:01 -0400687 mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
688 R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
689 mDismissView.setOnButtonClickListener(new View.OnClickListener() {
690 @Override
691 public void onClick(View v) {
692 clearAllNotifications();
693 }
694 });
695 mStackScroller.setDismissView(mDismissView);
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100696 mExpandedContents = mStackScroller;
Selim Cinek67b22602014-03-10 15:40:16 +0100697
Selim Cineka0fad3b2014-09-19 17:20:05 +0200698 mBackdrop = (BackDropView) mStatusBarWindow.findViewById(R.id.backdrop);
699 mBackdropFront = (ImageView) mBackdrop.findViewById(R.id.backdrop_front);
700 mBackdropBack = (ImageView) mBackdrop.findViewById(R.id.backdrop_back);
701
702 ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
703 ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
Selim Cinekaac93252015-04-14 20:04:12 -0700704 View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
705 mScrimController = new ScrimController(scrimBehind, scrimInFront, headsUpScrim,
706 mScrimSrcModeEnabled);
707 mHeadsUpManager.addListener(mScrimController);
708 mStackScroller.setScrimController(mScrimController);
Selim Cineka0fad3b2014-09-19 17:20:05 +0200709 mScrimController.setBackDropView(mBackdrop);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200710 mStatusBarView.setScrimController(mScrimController);
Jorim Jaggi048af1f2014-11-11 22:51:10 +0100711 mDozeScrimController = new DozeScrimController(mScrimController, context);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200712
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200713 mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header);
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200714 mHeader.setActivityStarter(this);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200715 mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200716 mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200717 mKeyguardBottomArea =
718 (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
719 mKeyguardBottomArea.setActivityStarter(this);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200720 mKeyguardIndicationController = new KeyguardIndicationController(mContext,
721 (KeyguardIndicationTextView) mStatusBarWindow.findViewById(
722 R.id.keyguard_indication_text));
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200723 mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400724
Joe Onorato808182d2010-07-09 18:52:06 -0400725 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
726
Joe Onorato808182d2010-07-09 18:52:06 -0400727 // set the inital view visibility
728 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400729
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100730 mIconController = new StatusBarIconController(
731 mContext, mStatusBarView, mKeyguardStatusBar, this);
732
Jason Monk4ae97d32014-12-17 10:14:33 -0500733 // Background thread for any controllers that need it.
734 mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
735 mHandlerThread.start();
736
Daniel Sandler2b697352011-07-22 16:23:09 -0400737 // Other icons
John Spurlockaf8d6c42014-05-07 17:49:08 -0400738 mLocationController = new LocationControllerImpl(mContext); // will post a notification
Daniel Sandler2b697352011-07-22 16:23:09 -0400739 mBatteryController = new BatteryController(mContext);
John Spurlock0ff62e02014-07-22 16:15:08 -0400740 mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
741 @Override
742 public void onPowerSaveChanged() {
743 mHandler.post(mCheckBarModes);
John Spurlockd96179e2014-08-21 16:43:45 -0400744 if (mDozeServiceHost != null) {
745 mDozeServiceHost.firePowerSaveChanged(mBatteryController.isPowerSave());
746 }
John Spurlock0ff62e02014-07-22 16:15:08 -0400747 }
748 @Override
749 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
750 // noop
751 }
752 });
John Spurlockaf8d6c42014-05-07 17:49:08 -0400753 mNetworkController = new NetworkControllerImpl(mContext);
Jason Monk51e4dc02014-07-22 12:00:47 -0400754 mHotspotController = new HotspotControllerImpl(mContext);
Jason Monk4ae97d32014-12-17 10:14:33 -0500755 mBluetoothController = new BluetoothControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monk3d5f5512014-07-25 11:17:28 -0400756 mSecurityController = new SecurityControllerImpl(mContext);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400757 if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) {
758 mRotationLockController = new RotationLockControllerImpl(mContext);
John Spurlock8ab172e2013-12-19 16:39:23 -0500759 }
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200760 mUserInfoController = new UserInfoController(mContext);
John Spurlock86005342014-05-23 11:58:00 -0400761 mVolumeComponent = getComponent(VolumeComponent.class);
John Spurlockf2565a82014-10-23 20:16:22 -0400762 if (mVolumeComponent != null) {
763 mZenModeController = mVolumeComponent.getZenController();
764 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400765 mCastController = new CastControllerImpl(mContext);
Jim Miller5e6af442011-12-02 18:24:26 -0800766 final SignalClusterView signalCluster =
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200767 (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
768 final SignalClusterView signalClusterKeyguard =
769 (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
Jorim Jaggi06d551a2014-09-02 15:55:57 +0200770 final SignalClusterView signalClusterQs =
771 (SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
Christian Robertson2e347422011-08-11 14:01:04 -0700772 mNetworkController.addSignalCluster(signalCluster);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200773 mNetworkController.addSignalCluster(signalClusterKeyguard);
Jorim Jaggi06d551a2014-09-02 15:55:57 +0200774 mNetworkController.addSignalCluster(signalClusterQs);
Jason Monk3128f122014-09-03 13:18:57 -0400775 signalCluster.setSecurityController(mSecurityController);
Daniel Sandler28f89d42011-08-15 14:04:15 -0400776 signalCluster.setNetworkController(mNetworkController);
Jason Monk3128f122014-09-03 13:18:57 -0400777 signalClusterKeyguard.setSecurityController(mSecurityController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200778 signalClusterKeyguard.setNetworkController(mNetworkController);
Jason Monk3128f122014-09-03 13:18:57 -0400779 signalClusterQs.setSecurityController(mSecurityController);
Jorim Jaggi06d551a2014-09-02 15:55:57 +0200780 signalClusterQs.setNetworkController(mNetworkController);
Daniel Sandler8b268d42013-05-28 16:17:13 -0400781 final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
782 if (isAPhone) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500783 mNetworkController.addEmergencyListener(new NetworkControllerImpl.EmergencyListener() {
784 @Override
785 public void setEmergencyCallsOnly(boolean emergencyOnly) {
786 mHeader.setShowEmergencyCallsOnly(emergencyOnly);
787 }
788 });
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400789 }
790
Adrian Roosb83777b2014-06-30 15:11:53 +0200791 mFlashlightController = new FlashlightController(mContext);
Adrian Roos1e1d6ac2014-07-22 17:18:55 +0200792 mKeyguardBottomArea.setFlashlightController(mFlashlightController);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200793 mKeyguardBottomArea.setPhoneStatusBar(this);
794 mAccessibilityController = new AccessibilityController(mContext);
795 mKeyguardBottomArea.setAccessibilityController(mAccessibilityController);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200796 mNextAlarmController = new NextAlarmController(mContext);
John Spurlock657c62c2014-07-22 12:18:09 -0400797 mKeyguardMonitor = new KeyguardMonitor();
Adrian Roos2b154a92014-11-17 15:18:39 +0100798 if (UserSwitcherController.isUserSwitcherAvailable(UserManager.get(mContext))) {
799 mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor);
800 }
Adrian Roos723632e2014-07-23 21:13:21 +0200801 mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200802 (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
Jorim Jaggibf1899e2014-08-07 02:04:18 +0200803 mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
Adrian Roos723632e2014-07-23 21:13:21 +0200804
805
John Spurlockaf8d6c42014-05-07 17:49:08 -0400806 // Set up the quick settings tile panel
807 mQSPanel = (QSPanel) mStatusBarWindow.findViewById(R.id.quick_settings_panel);
808 if (mQSPanel != null) {
809 final QSTileHost qsh = new QSTileHost(mContext, this,
810 mBluetoothController, mLocationController, mRotationLockController,
Jason Monk51e4dc02014-07-22 12:00:47 -0400811 mNetworkController, mZenModeController, mHotspotController,
John Spurlock657c62c2014-07-22 12:18:09 -0400812 mCastController, mFlashlightController,
Jason Monk3d5f5512014-07-25 11:17:28 -0400813 mUserSwitcherController, mKeyguardMonitor,
814 mSecurityController);
Adrian Roos1ef80fe2014-07-14 22:53:54 +0200815 mQSPanel.setHost(qsh);
John Spurlockbceed062014-08-10 18:04:16 -0400816 mQSPanel.setTiles(qsh.getTiles());
Adrian Roos5fd872e2014-08-12 17:28:58 +0200817 mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
818 mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400819 mHeader.setQSPanel(mQSPanel);
John Spurlockbceed062014-08-10 18:04:16 -0400820 qsh.setCallback(new QSTileHost.Callback() {
821 @Override
822 public void onTilesChanged() {
823 mQSPanel.setTiles(qsh.getTiles());
824 }
825 });
Siva Velusamy537421b2012-09-14 14:45:02 -0700826 }
827
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200828 // User info. Trigger first load.
829 mHeader.setUserInfoController(mUserInfoController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200830 mKeyguardStatusBar.setUserInfoController(mUserInfoController);
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200831 mUserInfoController.reloadUserInfo();
832
Jorim Jaggi853b0702014-07-05 04:31:14 +0200833 mHeader.setBatteryController(mBatteryController);
Jorim Jaggi708f7722014-08-20 17:30:38 +0200834 ((BatteryMeterView) mStatusBarView.findViewById(R.id.battery)).setBatteryController(
835 mBatteryController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200836 mKeyguardStatusBar.setBatteryController(mBatteryController);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200837 mHeader.setNextAlarmController(mNextAlarmController);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200838
John Spurlock56d007b2013-10-28 18:40:56 -0400839 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
840 mBroadcastReceiver.onReceive(mContext,
841 new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
842
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700843 mAssistGestureManager = new AssistGestureManager(this, context);
844
Joe Onorato808182d2010-07-09 18:52:06 -0400845 // receive broadcasts
846 IntentFilter filter = new IntentFilter();
Joe Onorato808182d2010-07-09 18:52:06 -0400847 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
848 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -0400849 filter.addAction(Intent.ACTION_SCREEN_ON);
Dan Sandler16128f42014-05-21 12:48:22 -0400850 if (DEBUG_MEDIA_FAKE_ARTWORK) {
851 filter.addAction("fake_artwork");
852 }
John Spurlock3c875662013-08-31 15:07:25 -0400853 filter.addAction(ACTION_DEMO);
Kenny Guy44fc65f2014-11-28 22:18:14 +0000854 context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
Joe Onorato808182d2010-07-09 18:52:06 -0400855
John Spurlock919adac2012-10-02 16:41:12 -0400856 // listen for USER_SETUP_COMPLETE setting (per-user)
857 resetUserSetupObserver();
858
Daniel Sandlera310af82012-04-24 01:20:13 -0400859 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -0400860 }
861
Dan Sandlereceda3d2014-07-21 15:35:01 -0400862 private void clearAllNotifications() {
863
864 // animate-swipe all dismissable notifications, then animate the shade closed
865 int numChildren = mStackScroller.getChildCount();
866
867 final ArrayList<View> viewsToHide = new ArrayList<View>(numChildren);
868 for (int i = 0; i < numChildren; i++) {
869 final View child = mStackScroller.getChildAt(i);
Selim Cinekb5605e52015-02-20 18:21:41 +0100870 if (child instanceof ExpandableNotificationRow) {
871 if (mStackScroller.canChildBeDismissed(child)) {
872 if (child.getVisibility() == View.VISIBLE) {
873 viewsToHide.add(child);
874 }
875 }
876 ExpandableNotificationRow row = (ExpandableNotificationRow) child;
877 List<ExpandableNotificationRow> children = row.getNotificationChildren();
878 if (row.areChildrenExpanded() && children != null) {
879 for (ExpandableNotificationRow childRow : children) {
880 if (childRow.getVisibility() == View.VISIBLE) {
881 viewsToHide.add(childRow);
882 }
883 }
Dan Sandlereceda3d2014-07-21 15:35:01 -0400884 }
885 }
886 }
887 if (viewsToHide.isEmpty()) {
888 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
889 return;
890 }
891
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200892 addPostCollapseAction(new Runnable() {
Dan Sandlereceda3d2014-07-21 15:35:01 -0400893 @Override
894 public void run() {
895 try {
896 mBarService.onClearAllNotifications(mCurrentUserId);
897 } catch (Exception ex) { }
898 }
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200899 });
Dan Sandlereceda3d2014-07-21 15:35:01 -0400900
901 performDismissAllAnimations(viewsToHide);
902
903 }
904
905 private void performDismissAllAnimations(ArrayList<View> hideAnimatedList) {
906 Runnable animationFinishAction = new Runnable() {
907 @Override
908 public void run() {
909 mStackScroller.post(new Runnable() {
910 @Override
911 public void run() {
912 mStackScroller.setDismissAllInProgress(false);
913 }
914 });
915 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
916 }
917 };
918
919 // let's disable our normal animations
920 mStackScroller.setDismissAllInProgress(true);
921
922 // Decrease the delay for every row we animate to give the sense of
923 // accelerating the swipes
924 int rowDelayDecrement = 10;
925 int currentDelay = 140;
Selim Cinek7d5f3742014-11-07 18:07:49 +0100926 int totalDelay = 180;
Dan Sandlereceda3d2014-07-21 15:35:01 -0400927 int numItems = hideAnimatedList.size();
Selim Cinek7d5f3742014-11-07 18:07:49 +0100928 for (int i = numItems - 1; i >= 0; i--) {
Dan Sandlereceda3d2014-07-21 15:35:01 -0400929 View view = hideAnimatedList.get(i);
930 Runnable endRunnable = null;
Selim Cinek7d5f3742014-11-07 18:07:49 +0100931 if (i == 0) {
Dan Sandlereceda3d2014-07-21 15:35:01 -0400932 endRunnable = animationFinishAction;
933 }
934 mStackScroller.dismissViewAnimated(view, endRunnable, totalDelay, 260);
935 currentDelay = Math.max(50, currentDelay - rowDelayDecrement);
936 totalDelay += currentDelay;
937 }
938 }
939
John Spurlockae641c92014-06-30 18:11:40 -0400940 @Override
941 protected void setZenMode(int mode) {
942 super.setZenMode(mode);
943 if (mIconPolicy != null) {
944 mIconPolicy.setZenMode(mode);
945 }
946 }
947
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100948 private void startKeyguard() {
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200949 KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
950 mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200951 mStatusBarWindow, mStatusBarWindowManager, mScrimController);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200952 mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100953 }
954
Michael Jurka7f2668c2012-03-27 07:49:52 -0700955 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -0700956 protected View getStatusBarView() {
957 return mStatusBarView;
958 }
959
Jorim Jaggi0a27be82014-06-11 03:22:39 +0200960 public StatusBarWindowView getStatusBarWindow() {
961 return mStatusBarWindow;
962 }
963
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700964 public void invokeAssistGesture(boolean vibrate) {
965 mHandler.removeCallbacks(mInvokeAssist);
966 mAssistGestureManager.onGestureInvoked(vibrate);
Jim Millere898ac52012-04-06 17:10:57 -0700967 }
968
Joe Onoratodc100302011-01-11 17:07:41 -0800969 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -0400970 if (mNaturalBarHeight < 0) {
971 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -0700972 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -0400973 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
974 }
975 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -0800976 }
977
Daniel Sandler5c8da942011-06-28 00:29:04 -0400978 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
979 public void onClick(View v) {
John Spurlockc8b46ca2013-04-08 12:59:26 -0400980 awakenDreams();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400981 toggleRecentApps();
982 }
983 };
Chris Wren0c8275b2012-05-08 13:36:48 -0400984
Jason Monk815e0572014-08-12 17:26:36 -0400985 private long mLastLockToAppLongPress;
Jason Monk815e0572014-08-12 17:26:36 -0400986 private View.OnLongClickListener mLongPressBackRecentsListener =
987 new View.OnLongClickListener() {
Jason Monk62515be2014-05-21 16:06:19 -0400988 @Override
989 public boolean onLongClick(View v) {
Jason Monk815e0572014-08-12 17:26:36 -0400990 handleLongPressBackRecents(v);
Jason Monk62515be2014-05-21 16:06:19 -0400991 return true;
992 }
993 };
994
Jim Miller9a720f52012-05-30 03:19:43 -0700995 private int mShowSearchHoldoff = 0;
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700996 private Runnable mInvokeAssist = new Runnable() {
Jim Miller9a720f52012-05-30 03:19:43 -0700997 public void run() {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700998 invokeAssistGesture(true /* vibrate */);
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400999 awakenDreams();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001000 if (mNavigationBarView != null) {
1001 mNavigationBarView.getHomeButton().abortCurrentGesture();
1002 }
Jim Miller9a720f52012-05-30 03:19:43 -07001003 }
1004 };
1005
Jorim Jaggi7b0de292014-05-27 21:41:55 +02001006 View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
Jim Millere898ac52012-04-06 17:10:57 -07001007 public boolean onTouch(View v, MotionEvent event) {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001008 switch (event.getAction()) {
Jorim Jaggif4797922014-08-04 22:49:41 +02001009 case MotionEvent.ACTION_DOWN:
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001010 if (!shouldDisableNavbarGestures()) {
1011 mHandler.removeCallbacks(mInvokeAssist);
1012 mHandler.postDelayed(mInvokeAssist, mShowSearchHoldoff);
1013 }
1014 break;
Jim Miller9a720f52012-05-30 03:19:43 -07001015
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001016 case MotionEvent.ACTION_UP:
1017 case MotionEvent.ACTION_CANCEL:
1018 mHandler.removeCallbacks(mInvokeAssist);
1019 awakenDreams();
1020 break;
1021 }
1022 return false;
Jim Millere898ac52012-04-06 17:10:57 -07001023 }
1024 };
Daniel Sandler5c8da942011-06-28 00:29:04 -04001025
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001026 private void awakenDreams() {
1027 if (mDreamManager != null) {
1028 try {
1029 mDreamManager.awaken();
1030 } catch (RemoteException e) {
1031 // fine, stay asleep then
1032 }
1033 }
1034 }
1035
Michael Jurka412cba82011-10-17 09:05:00 -07001036 private void prepareNavigationBarView() {
1037 mNavigationBarView.reorient();
1038
1039 mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
Michael Jurka80343f62012-10-18 13:13:46 +02001040 mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
Jason Monk62515be2014-05-21 16:06:19 -04001041 mNavigationBarView.getRecentsButton().setLongClickable(true);
Jason Monk815e0572014-08-12 17:26:36 -04001042 mNavigationBarView.getRecentsButton().setOnLongClickListener(mLongPressBackRecentsListener);
1043 mNavigationBarView.getBackButton().setLongClickable(true);
1044 mNavigationBarView.getBackButton().setOnLongClickListener(mLongPressBackRecentsListener);
Jorim Jaggi7b0de292014-05-27 21:41:55 +02001045 mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener);
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001046 mAssistGestureManager.onConfigurationChanged();
Michael Jurka412cba82011-10-17 09:05:00 -07001047 }
1048
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001049 // For small-screen devices (read: phones) that lack hardware navigation buttons
1050 private void addNavigationBar() {
John Spurlockcd686b52013-06-05 10:13:46 -04001051 if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -04001052 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001053
Michael Jurka412cba82011-10-17 09:05:00 -07001054 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001055
Jeff Brown98365d72012-08-19 20:30:52 -07001056 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001057 }
1058
1059 private void repositionNavigationBar() {
John Spurlock56d007b2013-10-28 18:40:56 -04001060 if (mNavigationBarView == null || !mNavigationBarView.isAttachedToWindow()) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001061
Michael Jurka412cba82011-10-17 09:05:00 -07001062 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001063
Jeff Brown98365d72012-08-19 20:30:52 -07001064 mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001065 }
1066
John Spurlock1bbd49d2012-10-19 11:09:32 -04001067 private void notifyNavigationBarScreenOn(boolean screenOn) {
1068 if (mNavigationBarView == null) return;
1069 mNavigationBarView.notifyScreenOn(screenOn);
1070 }
1071
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001072 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001073 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -07001074 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001075 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
1076 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001077 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
1078 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -07001079 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -04001080 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jim Millerd99e7fd2012-05-08 16:30:42 -07001081 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
John Spurlockad3e6cb2013-04-30 08:47:43 -04001082 PixelFormat.TRANSLUCENT);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001083 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -07001084 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001085 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
1086 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001087
1088 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001089 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001090 return lp;
1091 }
1092
Joe Onorato808182d2010-07-09 18:52:06 -04001093 public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001094 mIconController.addSystemIcon(slot, index, viewIndex, icon);
Joe Onorato808182d2010-07-09 18:52:06 -04001095 }
1096
1097 public void updateIcon(String slot, int index, int viewIndex,
1098 StatusBarIcon old, StatusBarIcon icon) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001099 mIconController.updateSystemIcon(slot, index, viewIndex, old, icon);
Joe Onorato808182d2010-07-09 18:52:06 -04001100 }
1101
1102 public void removeIcon(String slot, int index, int viewIndex) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001103 mIconController.removeSystemIcon(slot, index, viewIndex);
Joe Onorato808182d2010-07-09 18:52:06 -04001104 }
1105
John Spurlockbf20eab2014-04-09 16:40:39 -04001106 public UserHandle getCurrentUserHandle() {
1107 return new UserHandle(mCurrentUserId);
1108 }
1109
Christoph Studer71f18fd2014-05-20 17:02:04 +02001110 @Override
Selim Cinek379ff8f2015-02-20 17:03:16 +01001111 public void addNotification(StatusBarNotification notification, RankingMap ranking,
1112 Entry oldEntry) {
Chris Wrenaaa58d12014-06-03 14:29:12 -04001113 if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
Chris Wrend4db6cb2013-08-07 16:05:23 -04001114
Selim Cinek8d490d42015-04-10 00:05:50 -07001115 Entry shadeEntry = createNotificationViews(notification);
Chris Wrena4ef6202014-06-09 18:07:30 -04001116 if (shadeEntry == null) {
1117 return;
1118 }
Selim Cinek31d9ef72015-04-15 19:29:49 -07001119 boolean isHeadsUped = mUseHeadsUp && shouldInterrupt(notification);
1120 if (isHeadsUped) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001121 mHeadsUpManager.showNotification(shadeEntry);
1122 }
Chris Wrena4ef6202014-06-09 18:07:30 -04001123
Selim Cinek31d9ef72015-04-15 19:29:49 -07001124 if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
John Spurlockbf20eab2014-04-09 16:40:39 -04001125 // Stop screensaver if the notification has a full-screen intent.
1126 // (like an incoming phone call)
1127 awakenDreams();
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -04001128
John Spurlockbf20eab2014-04-09 16:40:39 -04001129 // not immersive & a full-screen alert should be shown
1130 if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
1131 try {
Chris Wren223c66b62014-11-10 16:00:09 -05001132 EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
1133 notification.getKey());
John Spurlockbf20eab2014-04-09 16:40:39 -04001134 notification.getNotification().fullScreenIntent.send();
1135 } catch (PendingIntent.CanceledException e) {
1136 }
Joe Onorato808182d2010-07-09 18:52:06 -04001137 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001138 addNotificationViews(shadeEntry, ranking);
Joe Onorato808182d2010-07-09 18:52:06 -04001139 // Recalculate the position of the sliding windows and the titles.
1140 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001141 }
1142
Chris Wren51c75102013-07-16 20:49:17 -04001143 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001144 protected void updateNotificationRanking(RankingMap ranking) {
Chris Wren333a61c2014-05-28 16:40:57 -04001145 mNotificationData.updateRanking(ranking);
Chris Wren333a61c2014-05-28 16:40:57 -04001146 updateNotifications();
1147 }
1148
1149 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001150 public void removeNotification(String key, RankingMap ranking) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001151 boolean defferRemoval = false;
1152 if (mHeadsUpManager.isHeadsUp(key)) {
1153 defferRemoval = !mHeadsUpManager.removeNotification(key);
Chris Wrena4ef6202014-06-09 18:07:30 -04001154 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001155 if (defferRemoval) {
1156 mLatestRankingMap = ranking;
1157 mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
1158 return;
1159 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001160 StatusBarNotification old = removeNotificationViews(key, ranking);
John Spurlockcd686b52013-06-05 10:13:46 -04001161 if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -04001162
1163 if (old != null) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001164 if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
Jorim Jaggiba94f882014-08-20 19:23:55 +02001165 && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02001166 if (mState == StatusBarState.SHADE) {
1167 animateCollapsePanels();
1168 } else if (mState == StatusBarState.SHADE_LOCKED) {
1169 goToKeyguard();
1170 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -04001171 }
Joe Onorato808182d2010-07-09 18:52:06 -04001172 }
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001173 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001174 }
1175
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001176 @Override
1177 protected void refreshLayout(int layoutDirection) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001178 if (mNavigationBarView != null) {
1179 mNavigationBarView.setLayoutDirection(layoutDirection);
1180 }
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001181 }
1182
John Spurlockd5ef5462012-06-13 11:19:51 -04001183 private void updateShowSearchHoldoff() {
1184 mShowSearchHoldoff = mContext.getResources().getInteger(
1185 R.integer.config_show_search_delay);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001186 }
1187
Christoph Studer37fe6932014-05-26 13:10:30 +02001188 private void updateNotificationShade() {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001189 if (mStackScroller == null) return;
Daniel Sandler26cda272012-05-22 15:44:08 -04001190
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001191 // Do not modify the notifications during collapse.
1192 if (isCollapsing()) {
1193 addPostCollapseAction(new Runnable() {
1194 @Override
1195 public void run() {
1196 updateNotificationShade();
1197 }
1198 });
1199 return;
1200 }
1201
Christoph Studerc8db24b2014-07-25 17:50:30 +02001202 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
Jorim Jaggif6411742014-08-05 17:10:43 +00001203 ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size());
Christoph Studerc8db24b2014-07-25 17:50:30 +02001204 final int N = activeNotifications.size();
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001205 for (int i=0; i<N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001206 Entry ent = activeNotifications.get(i);
1207 int vis = ent.notification.getNotification().visibility;
Kenny Guy3a7c4a52014-03-03 18:24:03 +00001208
Christoph Studerc8db24b2014-07-25 17:50:30 +02001209 // Display public version of the notification if we need to redact.
Jorim Jaggiae441282014-08-01 02:45:18 +02001210 final boolean hideSensitive =
1211 !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId());
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001212 boolean sensitiveNote = vis == Notification.VISIBILITY_PRIVATE;
1213 boolean sensitivePackage = packageHasVisibilityOverride(ent.notification.getKey());
1214 boolean sensitive = (sensitiveNote && hideSensitive) || sensitivePackage;
1215 boolean showingPublic = sensitive && isLockscreenPublicMode();
1216 ent.row.setSensitive(sensitive);
Dan Sandler1b718782014-07-18 12:43:45 -04001217 if (ent.autoRedacted && ent.legacy) {
Jorim Jaggiae441282014-08-01 02:45:18 +02001218 // TODO: Also fade this? Or, maybe easier (and better), provide a dark redacted form
1219 // for legacy auto redacted notifications.
Dan Sandler1b718782014-07-18 12:43:45 -04001220 if (showingPublic) {
1221 ent.row.setShowingLegacyBackground(false);
1222 } else {
1223 ent.row.setShowingLegacyBackground(true);
1224 }
1225 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001226 if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
1227 ExpandableNotificationRow summary = mGroupManager.getGroupSummary(
1228 ent.row.getStatusBarNotification());
1229 List<ExpandableNotificationRow> orderedChildren =
1230 mTmpChildOrderMap.get(summary);
1231 if (orderedChildren == null) {
1232 orderedChildren = new ArrayList<>();
1233 mTmpChildOrderMap.put(summary, orderedChildren);
1234 }
1235 orderedChildren.add(ent.row);
1236 } else {
1237 toShow.add(ent.row);
1238 }
1239
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001240 }
1241
Selim Cinekb5605e52015-02-20 18:21:41 +01001242 ArrayList<View> toRemove = new ArrayList<>();
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001243 for (int i=0; i< mStackScroller.getChildCount(); i++) {
1244 View child = mStackScroller.getChildAt(i);
Jorim Jaggif6411742014-08-05 17:10:43 +00001245 if (!toShow.contains(child) && child instanceof ExpandableNotificationRow) {
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001246 toRemove.add(child);
Joe Onorato808182d2010-07-09 18:52:06 -04001247 }
1248 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001249
1250 for (View remove : toRemove) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001251 mStackScroller.removeView(remove);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001252 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001253 for (int i=0; i<toShow.size(); i++) {
1254 View v = toShow.get(i);
1255 if (v.getParent() == null) {
Christoph Studer37fe6932014-05-26 13:10:30 +02001256 mStackScroller.addView(v);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001257 }
1258 }
Daniel Sandler26cda272012-05-22 15:44:08 -04001259
Christoph Studer37fe6932014-05-26 13:10:30 +02001260 // So after all this work notifications still aren't sorted correctly.
1261 // Let's do that now by advancing through toShow and mStackScroller in
1262 // lock-step, making sure mStackScroller matches what we see in toShow.
1263 int j = 0;
1264 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1265 View child = mStackScroller.getChildAt(i);
1266 if (!(child instanceof ExpandableNotificationRow)) {
1267 // We don't care about non-notification views.
1268 continue;
1269 }
1270
Selim Cinekb5605e52015-02-20 18:21:41 +01001271 ExpandableNotificationRow targetChild = toShow.get(j);
1272 if (child != targetChild) {
1273 // Oops, wrong notification at this position. Put the right one
1274 // here and advance both lists.
1275 mStackScroller.changeViewPosition(targetChild, i);
Christoph Studer37fe6932014-05-26 13:10:30 +02001276 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001277 j++;
Selim Cinekb5605e52015-02-20 18:21:41 +01001278
Christoph Studer37fe6932014-05-26 13:10:30 +02001279 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001280
1281 // lets handle the child notifications now
1282 updateNotificationShadeForChildren();
1283
1284 // clear the map again for the next usage
1285 mTmpChildOrderMap.clear();
1286
Christoph Studer37fe6932014-05-26 13:10:30 +02001287 updateRowStates();
Jorim Jaggif6411742014-08-05 17:10:43 +00001288 updateSpeedbump();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001289 updateClearAll();
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001290 updateEmptyShadeView();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001291
Jason Monk3ad242d2014-09-15 11:13:35 -04001292 // Disable QS if device not provisioned.
1293 // If the user switcher is simple then disable QS during setup because
1294 // the user intends to use the lock screen user switcher, QS in not needed.
1295 mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned()
Adrian Roos2b154a92014-11-17 15:18:39 +01001296 && (mUserSetup || mUserSwitcherController == null
1297 || !mUserSwitcherController.isSimpleUserSwitcher()));
John Spurlockbf370992014-06-17 13:58:31 -04001298 mShadeUpdates.check();
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001299 }
1300
Selim Cinekb5605e52015-02-20 18:21:41 +01001301 private void updateNotificationShadeForChildren() {
1302 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
1303 boolean orderChanged = false;
1304 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1305 View view = mStackScroller.getChildAt(i);
1306 if (!(view instanceof ExpandableNotificationRow)) {
1307 // We don't care about non-notification views.
1308 continue;
1309 }
1310
1311 ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
1312 List<ExpandableNotificationRow> children = parent.getNotificationChildren();
1313 List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
1314
1315 // lets first remove all undesired children
1316 if (children != null) {
1317 toRemove.clear();
1318 for (ExpandableNotificationRow childRow : children) {
1319 if (orderedChildren == null || !orderedChildren.contains(childRow)) {
1320 toRemove.add(childRow);
1321 }
1322 }
1323 for (ExpandableNotificationRow remove : toRemove) {
1324 parent.removeChildNotification(remove);
1325 mStackScroller.notifyGroupChildRemoved(remove);
1326 }
1327 }
1328
1329 // We now add all the children which are not in there already
1330 for (int childIndex = 0; orderedChildren != null && childIndex < orderedChildren.size();
1331 childIndex++) {
1332 ExpandableNotificationRow childView = orderedChildren.get(childIndex);
1333 if (children == null || !children.contains(childView)) {
1334 parent.addChildNotification(childView, childIndex);
1335 mStackScroller.notifyGroupChildAdded(childView);
1336 }
1337 }
1338
1339 // Finally after removing and adding has been beformed we can apply the order.
1340 orderChanged |= parent.applyChildOrder(orderedChildren);
1341 }
1342 if (orderChanged) {
1343 mStackScroller.generateChildOrderChangedEvent();
1344 }
1345 }
1346
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001347 private boolean packageHasVisibilityOverride(String key) {
1348 return mNotificationData.getVisibilityOverride(key)
1349 != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
1350 }
1351
Dan Sandlereceda3d2014-07-21 15:35:01 -04001352 private void updateClearAll() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001353 boolean showDismissView =
1354 mState != StatusBarState.KEYGUARD &&
1355 mNotificationData.hasActiveClearableNotifications();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001356 mStackScroller.updateDismissView(showDismissView);
1357 }
1358
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001359 private void updateEmptyShadeView() {
1360 boolean showEmptyShade =
1361 mState != StatusBarState.KEYGUARD &&
1362 mNotificationData.getActiveNotifications().size() == 0;
1363 mNotificationPanel.setShadeEmpty(showEmptyShade);
1364 }
1365
Jorim Jaggif6411742014-08-05 17:10:43 +00001366 private void updateSpeedbump() {
1367 int speedbumpIndex = -1;
1368 int currentIndex = 0;
1369 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
1370 final int N = activeNotifications.size();
1371 for (int i = 0; i < N; i++) {
1372 Entry entry = activeNotifications.get(i);
Selim Cinekb5605e52015-02-20 18:21:41 +01001373 boolean isChild = !isTopLevelChild(entry);
1374 if (isChild) {
1375 continue;
1376 }
Jorim Jaggif6411742014-08-05 17:10:43 +00001377 if (entry.row.getVisibility() != View.GONE &&
1378 mNotificationData.isAmbient(entry.key)) {
1379 speedbumpIndex = currentIndex;
1380 break;
1381 }
1382 currentIndex++;
1383 }
1384 mStackScroller.updateSpeedBumpIndex(speedbumpIndex);
1385 }
1386
Selim Cinekb5605e52015-02-20 18:21:41 +01001387 public static boolean isTopLevelChild(Entry entry) {
1388 return entry.row.getParent() instanceof NotificationStackScrollLayout;
1389 }
1390
Chris Wren0c8275b2012-05-08 13:36:48 -04001391 @Override
Christoph Studer37fe6932014-05-26 13:10:30 +02001392 protected void updateNotifications() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001393 mNotificationData.filterAndSort();
1394
Christoph Studer37fe6932014-05-26 13:10:30 +02001395 updateNotificationShade();
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001396 mIconController.updateNotificationIcons(mNotificationData);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001397 }
1398
Jorim Jaggi54045422014-07-03 18:30:40 +02001399 @Override
1400 protected void updateRowStates() {
1401 super.updateRowStates();
1402 mNotificationPanel.notifyVisibleChildrenChanged();
1403 }
1404
Chris Wren0c8275b2012-05-08 13:36:48 -04001405 @Override
1406 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001407
Chris Wren6d15a362013-08-20 18:46:29 -04001408 if (SPEW) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001409 final boolean clearable = hasActiveNotifications() &&
1410 mNotificationData.hasActiveClearableNotifications();
1411 Log.d(TAG, "setAreThereNotifications: N=" +
1412 mNotificationData.getActiveNotifications().size() + " any=" +
1413 hasActiveNotifications() + " clearable=" + clearable);
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001414 }
1415
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001416 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
Christoph Studerc8db24b2014-07-25 17:50:30 +02001417 final boolean showDot = hasActiveNotifications() && !areLightsOn();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001418 if (showDot != (nlo.getAlpha() == 1.0f)) {
1419 if (showDot) {
1420 nlo.setAlpha(0f);
1421 nlo.setVisibility(View.VISIBLE);
1422 }
1423 nlo.animate()
1424 .alpha(showDot?1:0)
1425 .setDuration(showDot?750:250)
1426 .setInterpolator(new AccelerateInterpolator(2.0f))
1427 .setListener(showDot ? null : new AnimatorListenerAdapter() {
1428 @Override
1429 public void onAnimationEnd(Animator _a) {
1430 nlo.setVisibility(View.GONE);
1431 }
1432 })
1433 .start();
1434 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04001435
Dan Sandler16128f42014-05-21 12:48:22 -04001436 findAndUpdateMediaNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001437 }
1438
Dan Sandler16128f42014-05-21 12:48:22 -04001439 public void findAndUpdateMediaNotifications() {
1440 boolean metaDataChanged = false;
1441
1442 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001443 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
1444 final int N = activeNotifications.size();
Dan Sandler16128f42014-05-21 12:48:22 -04001445 Entry mediaNotification = null;
1446 MediaController controller = null;
Christoph Studerc8db24b2014-07-25 17:50:30 +02001447 for (int i = 0; i < N; i++) {
1448 final Entry entry = activeNotifications.get(i);
Dan Sandler16128f42014-05-21 12:48:22 -04001449 if (isMediaNotification(entry)) {
1450 final MediaSession.Token token = entry.notification.getNotification().extras
1451 .getParcelable(Notification.EXTRA_MEDIA_SESSION);
1452 if (token != null) {
RoboErik031149c2014-07-25 16:00:52 -07001453 controller = new MediaController(mContext, token);
Dan Sandler16128f42014-05-21 12:48:22 -04001454 if (controller != null) {
1455 // we've got a live one, here
1456 mediaNotification = entry;
1457 }
1458 }
1459 }
1460 }
1461
1462 if (mediaNotification == null) {
1463 // Still nothing? OK, let's just look for live media sessions and see if they match
1464 // one of our notifications. This will catch apps that aren't (yet!) using media
1465 // notifications.
1466
1467 if (mMediaSessionManager != null) {
1468 final List<MediaController> sessions
1469 = mMediaSessionManager.getActiveSessionsForUser(
1470 null,
1471 UserHandle.USER_ALL);
1472
1473 for (MediaController aController : sessions) {
1474 if (aController == null) continue;
1475 final PlaybackState state = aController.getPlaybackState();
1476 if (state == null) continue;
1477 switch (state.getState()) {
1478 case PlaybackState.STATE_STOPPED:
1479 case PlaybackState.STATE_ERROR:
1480 continue;
1481 default:
1482 // now to see if we have one like this
RoboErikaa4e23b2014-07-24 18:35:11 -07001483 final String pkg = aController.getPackageName();
Dan Sandler16128f42014-05-21 12:48:22 -04001484
1485 for (int i = 0; i < N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001486 final Entry entry = activeNotifications.get(i);
Dan Sandler16128f42014-05-21 12:48:22 -04001487 if (entry.notification.getPackageName().equals(pkg)) {
1488 if (DEBUG_MEDIA) {
1489 Log.v(TAG, "DEBUG_MEDIA: found controller matching "
1490 + entry.notification.getKey());
1491 }
1492 controller = aController;
1493 mediaNotification = entry;
1494 break;
1495 }
1496 }
1497 }
1498 }
1499 }
1500 }
1501
Christoph Studerb5245d82014-09-19 16:54:36 +02001502 if (!sameSessions(mMediaController, controller)) {
Dan Sandler16128f42014-05-21 12:48:22 -04001503 // We have a new media session
1504
1505 if (mMediaController != null) {
1506 // something old was playing
1507 Log.v(TAG, "DEBUG_MEDIA: Disconnecting from old controller: "
1508 + mMediaController);
RoboErik14f717a2014-09-04 16:08:00 -07001509 mMediaController.unregisterCallback(mMediaListener);
Dan Sandler16128f42014-05-21 12:48:22 -04001510 }
1511 mMediaController = controller;
1512
1513 if (mMediaController != null) {
RoboErik14f717a2014-09-04 16:08:00 -07001514 mMediaController.registerCallback(mMediaListener);
Dan Sandler16128f42014-05-21 12:48:22 -04001515 mMediaMetadata = mMediaController.getMetadata();
1516 if (DEBUG_MEDIA) {
1517 Log.v(TAG, "DEBUG_MEDIA: insert listener, receive metadata: "
1518 + mMediaMetadata);
1519 }
1520
1521 final String notificationKey = mediaNotification == null
1522 ? null
1523 : mediaNotification.notification.getKey();
1524
1525 if (notificationKey == null || !notificationKey.equals(mMediaNotificationKey)) {
1526 // we have a new notification!
1527 if (DEBUG_MEDIA) {
1528 Log.v(TAG, "DEBUG_MEDIA: Found new media notification: key="
1529 + notificationKey + " controller=" + controller);
1530 }
1531 mMediaNotificationKey = notificationKey;
1532 }
1533 } else {
1534 mMediaMetadata = null;
1535 mMediaNotificationKey = null;
1536 }
1537
1538 metaDataChanged = true;
1539 } else {
1540 // Media session unchanged
1541
1542 if (DEBUG_MEDIA) {
1543 Log.v(TAG, "DEBUG_MEDIA: Continuing media notification: key=" + mMediaNotificationKey);
1544 }
1545 }
1546 }
1547
1548 updateMediaMetaData(metaDataChanged);
1549 }
1550
Christoph Studerb5245d82014-09-19 16:54:36 +02001551 private boolean sameSessions(MediaController a, MediaController b) {
1552 if (a == b) return true;
1553 if (a == null) return false;
1554 return a.controlsSameSession(b);
1555 }
1556
Dan Sandler16128f42014-05-21 12:48:22 -04001557 /**
Dan Sandler7dea0ee2014-07-21 21:07:15 -04001558 * Hide the album artwork that is fading out and release its bitmap.
Dan Sandler16128f42014-05-21 12:48:22 -04001559 */
1560 private Runnable mHideBackdropFront = new Runnable() {
1561 @Override
1562 public void run() {
1563 if (DEBUG_MEDIA) {
1564 Log.v(TAG, "DEBUG_MEDIA: removing fade layer");
1565 }
1566 mBackdropFront.setVisibility(View.INVISIBLE);
Dan Sandler7dea0ee2014-07-21 21:07:15 -04001567 mBackdropFront.animate().cancel();
1568 mBackdropFront.setImageDrawable(null);
Dan Sandler16128f42014-05-21 12:48:22 -04001569 }
1570 };
1571
1572 /**
1573 * Refresh or remove lockscreen artwork from media metadata.
1574 */
1575 public void updateMediaMetaData(boolean metaDataChanged) {
1576 if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) return;
1577
1578 if (mBackdrop == null) return; // called too early
1579
1580 if (DEBUG_MEDIA) {
1581 Log.v(TAG, "DEBUG_MEDIA: updating album art for notification " + mMediaNotificationKey
1582 + " metadata=" + mMediaMetadata
1583 + " metaDataChanged=" + metaDataChanged
1584 + " state=" + mState);
1585 }
1586
1587 Bitmap artworkBitmap = null;
1588 if (mMediaMetadata != null) {
1589 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
1590 if (artworkBitmap == null) {
1591 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
1592 // might still be null
1593 }
1594 }
1595
1596 final boolean hasArtwork = artworkBitmap != null;
1597
1598 if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
1599 && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
1600 // time to show some art!
1601 if (mBackdrop.getVisibility() != View.VISIBLE) {
1602 mBackdrop.setVisibility(View.VISIBLE);
1603 mBackdrop.animate().alpha(1f);
1604 metaDataChanged = true;
1605 if (DEBUG_MEDIA) {
1606 Log.v(TAG, "DEBUG_MEDIA: Fading in album artwork");
1607 }
1608 }
1609 if (metaDataChanged) {
1610 if (mBackdropBack.getDrawable() != null) {
Selim Cineka0fad3b2014-09-19 17:20:05 +02001611 Drawable drawable = mBackdropBack.getDrawable();
1612 mBackdropFront.setImageDrawable(drawable);
Jorim Jaggi0e664392014-09-27 01:30:22 +02001613 if (mScrimSrcModeEnabled) {
1614 mBackdropFront.getDrawable().mutate().setXfermode(mSrcOverXferMode);
1615 }
Dan Sandler16128f42014-05-21 12:48:22 -04001616 mBackdropFront.setAlpha(1f);
1617 mBackdropFront.setVisibility(View.VISIBLE);
1618 } else {
1619 mBackdropFront.setVisibility(View.INVISIBLE);
1620 }
1621
1622 if (DEBUG_MEDIA_FAKE_ARTWORK) {
1623 final int c = 0xFF000000 | (int)(Math.random() * 0xFFFFFF);
1624 Log.v(TAG, String.format("DEBUG_MEDIA: setting new color: 0x%08x", c));
1625 mBackdropBack.setBackgroundColor(0xFFFFFFFF);
1626 mBackdropBack.setImageDrawable(new ColorDrawable(c));
1627 } else {
1628 mBackdropBack.setImageBitmap(artworkBitmap);
1629 }
Jorim Jaggi0e664392014-09-27 01:30:22 +02001630 if (mScrimSrcModeEnabled) {
1631 mBackdropBack.getDrawable().mutate().setXfermode(mSrcXferMode);
1632 }
Dan Sandler16128f42014-05-21 12:48:22 -04001633
1634 if (mBackdropFront.getVisibility() == View.VISIBLE) {
1635 if (DEBUG_MEDIA) {
1636 Log.v(TAG, "DEBUG_MEDIA: Crossfading album artwork from "
1637 + mBackdropFront.getDrawable()
1638 + " to "
1639 + mBackdropBack.getDrawable());
1640 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02001641 mBackdropFront.animate()
Dan Sandler16128f42014-05-21 12:48:22 -04001642 .setDuration(250)
1643 .alpha(0f).withEndAction(mHideBackdropFront);
1644 }
1645 }
1646 } else {
1647 // need to hide the album art, either because we are unlocked or because
1648 // the metadata isn't there to support it
1649 if (mBackdrop.getVisibility() != View.GONE) {
1650 if (DEBUG_MEDIA) {
1651 Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
1652 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02001653 mBackdrop.animate()
1654 .alpha(0f)
1655 .setInterpolator(mBackdropInterpolator)
1656 .setDuration(300)
1657 .setStartDelay(0)
1658 .withEndAction(new Runnable() {
1659 @Override
1660 public void run() {
1661 mBackdrop.setVisibility(View.GONE);
1662 mBackdropFront.animate().cancel();
1663 mBackdropBack.animate().cancel();
1664 mHandler.post(mHideBackdropFront);
1665 }
1666 });
1667 if (mKeyguardFadingAway) {
1668 mBackdrop.animate()
1669
1670 // Make it disappear faster, as the focus should be on the activity behind.
1671 .setDuration(mKeyguardFadingAwayDuration / 2)
1672 .setStartDelay(mKeyguardFadingAwayDelay)
1673 .setInterpolator(mLinearInterpolator)
1674 .start();
1675 }
Dan Sandler16128f42014-05-21 12:48:22 -04001676 }
1677 }
1678 }
1679
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001680 private int adjustDisableFlags(int state) {
Selim Cinekbaa23272014-07-08 18:01:07 +02001681 if (!mLaunchTransitionFadingAway
1682 && (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001683 state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
1684 state |= StatusBarManager.DISABLE_SYSTEM_INFO;
1685 }
1686 return state;
1687 }
1688
Joe Onorato808182d2010-07-09 18:52:06 -04001689 /**
1690 * State is one or more of the DISABLE constants from StatusBarManager.
1691 */
Jorim Jaggi2580a9762014-06-25 03:08:25 +02001692 public void disable(int state, boolean animate) {
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001693 mDisabledUnmodified = state;
1694 state = adjustDisableFlags(state);
Joe Onorato808182d2010-07-09 18:52:06 -04001695 final int old = mDisabled;
1696 final int diff = state ^ old;
1697 mDisabled = state;
1698
Daniel Sandlere21f2882011-08-18 10:14:59 -04001699 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04001700 Log.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
Daniel Sandlere21f2882011-08-18 10:14:59 -04001701 old, state, diff));
1702 }
1703
Daniel Sandler6da2b762011-09-14 16:04:59 -04001704 StringBuilder flagdbg = new StringBuilder();
1705 flagdbg.append("disable: < ");
1706 flagdbg.append(((state & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
1707 flagdbg.append(((diff & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
1708 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
1709 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
1710 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
1711 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001712 flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
1713 flagdbg.append(((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001714 flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
1715 flagdbg.append(((diff & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
Daniel Sandlerdba93562011-10-06 16:39:58 -04001716 flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
1717 flagdbg.append(((diff & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
1718 flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
1719 flagdbg.append(((diff & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001720 flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
1721 flagdbg.append(((diff & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
Daniel Sandlerd5483c32012-10-19 16:44:15 -04001722 flagdbg.append(((state & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
1723 flagdbg.append(((diff & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001724 flagdbg.append(">");
John Spurlockcd686b52013-06-05 10:13:46 -04001725 Log.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07001726
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001727 if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001728 if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001729 mIconController.hideSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001730 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001731 mIconController.showSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001732 }
1733 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04001734
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001735 if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001736 boolean visible = (state & StatusBarManager.DISABLE_CLOCK) == 0;
1737 mIconController.setClockVisibility(visible);
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001738 }
Joe Onorato808182d2010-07-09 18:52:06 -04001739 if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
1740 if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001741 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04001742 }
1743 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001744
Jim Miller5e6af442011-12-02 18:24:26 -08001745 if ((diff & (StatusBarManager.DISABLE_HOME
1746 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerd5483c32012-10-19 16:44:15 -04001747 | StatusBarManager.DISABLE_BACK
1748 | StatusBarManager.DISABLE_SEARCH)) != 0) {
Daniel Sandlerdba93562011-10-06 16:39:58 -04001749 // the nav bar will take care of these
Daniel Sandlerd9283b902011-09-14 21:42:00 -04001750 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
Daniel Sandler6da2b762011-09-14 16:04:59 -04001751
Daniel Sandlerdba93562011-10-06 16:39:58 -04001752 if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04001753 // close recents if it's visible
Winson Chung1e8d71b2014-05-16 17:05:22 -07001754 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
1755 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
Daniel Sandler6da2b762011-09-14 16:04:59 -04001756 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001757 }
1758
Joe Onorato808182d2010-07-09 18:52:06 -04001759 if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1760 if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001761 mIconController.hideNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04001762 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001763 mIconController.showNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04001764 }
Joe Onorato808182d2010-07-09 18:52:06 -04001765 }
Jason Monkf7019542014-07-31 12:42:25 -04001766
1767 if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
1768 mDisableNotificationAlerts =
1769 (state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
1770 mHeadsUpObserver.onChange(true);
1771 }
Joe Onorato808182d2010-07-09 18:52:06 -04001772 }
1773
Michael Jurka7f2668c2012-03-27 07:49:52 -07001774 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07001775 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001776 return new PhoneStatusBar.H();
1777 }
1778
Jorim Jaggi97b63c42014-05-02 23:03:34 +02001779 @Override
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02001780 public void startActivity(Intent intent, boolean dismissShade) {
1781 startActivityDismissingKeyguard(intent, false, dismissShade);
Jorim Jaggi97b63c42014-05-02 23:03:34 +02001782 }
1783
Jorim Jaggib690f0d2014-07-03 23:25:44 +02001784 public void setQsExpanded(boolean expanded) {
1785 mStatusBarWindowManager.setQsExpanded(expanded);
1786 }
1787
Jorim Jaggi84a3e7a2014-08-13 17:58:58 +02001788 public boolean isGoingToNotificationShade() {
1789 return mLeaveOpenOnKeyguardHide;
1790 }
1791
Jorim Jaggid692dd02014-08-14 20:57:42 +02001792 public boolean isQsExpanded() {
1793 return mNotificationPanel.isQsExpanded();
1794 }
1795
Selim Cinek29ed3c92014-09-23 20:44:35 +02001796 public boolean isScreenOnComingFromTouch() {
1797 return mScreenOnComingFromTouch;
1798 }
1799
Selim Cinek19c8c702014-08-25 22:09:19 +02001800 public boolean isFalsingThresholdNeeded() {
1801 boolean onKeyguard = getBarState() == StatusBarState.KEYGUARD;
Christoph Studer2231c6e2014-12-19 12:40:13 +01001802 boolean isCurrentlyInsecure = mUnlockMethodCache.isCurrentlyInsecure();
1803 return onKeyguard && (isCurrentlyInsecure || mDozing || mScreenOnComingFromTouch);
Selim Cinek19c8c702014-08-25 22:09:19 +02001804 }
1805
John Spurlock0b99ea92014-10-01 15:32:22 -04001806 public boolean isDozing() {
1807 return mDozing;
1808 }
1809
Christoph Studer2e731b52014-08-22 16:01:51 +02001810 @Override // NotificationData.Environment
1811 public String getCurrentMediaNotificationKey() {
1812 return mMediaNotificationKey;
1813 }
1814
Jorim Jaggi0e664392014-09-27 01:30:22 +02001815 public boolean isScrimSrcModeEnabled() {
1816 return mScrimSrcModeEnabled;
1817 }
1818
Joe Onorato808182d2010-07-09 18:52:06 -04001819 /**
Christoph Studer2231c6e2014-12-19 12:40:13 +01001820 * To be called when there's a state change in StatusBarKeyguardViewManager.
1821 */
1822 public void onKeyguardViewManagerStatesUpdated() {
1823 logStateToEventlog();
1824 }
1825
1826 @Override // UnlockMethodCache.OnUnlockMethodChangedListener
1827 public void onUnlockMethodStateChanged() {
1828 logStateToEventlog();
1829 }
1830
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001831 @Override
1832 public void OnPinnedHeadsUpExistChanged(boolean exist, boolean changeImmediatly) {
1833 if (exist) {
1834 mStatusBarWindowManager.setHeadsUpShowing(true);
1835 } else {
1836 Runnable endRunnable = new Runnable() {
1837 @Override
1838 public void run() {
1839 if (!mHeadsUpManager.hasPinnedHeadsUp()) {
1840 mStatusBarWindowManager.setHeadsUpShowing(false);
1841 }
1842 }
1843 };
1844 if (changeImmediatly) {
1845 endRunnable.run();
1846 } else {
1847 mStackScroller.performOnAnimationFinished(endRunnable);
1848 }
1849 }
1850 }
1851
1852 @Override
Selim Cinekaac93252015-04-14 20:04:12 -07001853 public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) {
Selim Cinek1f3f5442015-04-10 17:54:46 -07001854 }
1855
1856 @Override
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001857 public void OnHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
1858 if (!isHeadsUp && mHeadsUpEntriesToRemoveOnSwitch.contains(entry)) {
1859 removeNotification(entry.key, mLatestRankingMap);
1860 mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
1861 if (mHeadsUpEntriesToRemoveOnSwitch.isEmpty()) {
1862 mLatestRankingMap = null;
1863 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07001864 } else {
1865 updateNotificationRanking(null);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001866 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07001867
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001868 }
1869
Christoph Studer2231c6e2014-12-19 12:40:13 +01001870 /**
Joe Onorato808182d2010-07-09 18:52:06 -04001871 * All changes to the status bar and notifications funnel through here and are batched.
1872 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07001873 private class H extends BaseStatusBar.H {
Joe Onorato808182d2010-07-09 18:52:06 -04001874 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001875 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04001876 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001877 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04001878 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001879 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04001880 case MSG_OPEN_SETTINGS_PANEL:
1881 animateExpandSettingsPanel();
1882 break;
1883 case MSG_CLOSE_PANELS:
1884 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001885 break;
Jorim Jaggi826730a2014-12-08 21:05:13 +01001886 case MSG_LAUNCH_TRANSITION_TIMEOUT:
1887 onLaunchTransitionTimeout();
1888 break;
Chris Wrene97f90b2013-08-07 17:39:35 -04001889 }
1890 }
1891 }
1892
Chris Wren930ecca2014-11-12 17:43:41 -05001893 @Override
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001894 public void escalateHeadsUp() {
Selim Cineka59ecc32015-04-07 10:51:49 -07001895 TreeSet<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getSortedEntries();
1896 for (HeadsUpManager.HeadsUpEntry entry : entries) {
1897 final StatusBarNotification sbn = entry.entry.notification;
Chris Wrene97f90b2013-08-07 17:39:35 -04001898 final Notification notification = sbn.getNotification();
1899 if (notification.fullScreenIntent != null) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001900 if (DEBUG) {
Chris Wrene97f90b2013-08-07 17:39:35 -04001901 Log.d(TAG, "converting a heads up to fullScreen");
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001902 }
Chris Wrene97f90b2013-08-07 17:39:35 -04001903 try {
Chris Wren223c66b62014-11-10 16:00:09 -05001904 EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
1905 sbn.getKey());
Chris Wrene97f90b2013-08-07 17:39:35 -04001906 notification.fullScreenIntent.send();
1907 } catch (PendingIntent.CanceledException e) {
1908 }
Joe Onorato808182d2010-07-09 18:52:06 -04001909 }
1910 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001911 mHeadsUpManager.releaseAllImmediately();
Joe Onorato808182d2010-07-09 18:52:06 -04001912 }
1913
John Spurlock97642182013-07-29 17:58:39 -04001914 boolean panelsEnabled() {
John Spurlock79ec2a12013-09-11 09:28:49 -04001915 return (mDisabled & StatusBarManager.DISABLE_EXPAND) == 0;
John Spurlock97642182013-07-29 17:58:39 -04001916 }
1917
Jorim Jaggifa505a72014-04-28 20:04:11 +02001918 void makeExpandedVisible(boolean force) {
John Spurlockcd686b52013-06-05 10:13:46 -04001919 if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
Jorim Jaggifa505a72014-04-28 20:04:11 +02001920 if (!force && (mExpandedVisible || !panelsEnabled())) {
Joe Onorato808182d2010-07-09 18:52:06 -04001921 return;
1922 }
Jim Millera073e572012-05-23 17:03:27 -07001923
Joe Onorato808182d2010-07-09 18:52:06 -04001924 mExpandedVisible = true;
John Spurlockd5ef5462012-06-13 11:19:51 -04001925 if (mNavigationBarView != null)
1926 mNavigationBarView.setSlippery(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001927
Daniel Sandlera310af82012-04-24 01:20:13 -04001928 // Expand the window to encompass the full screen in anticipation of the drag.
1929 // This is only possible to do atomically because the status bar is at the top of the screen!
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001930 mStatusBarWindowManager.setStatusBarExpanded(true);
Selim Cineke32010a2014-08-20 23:50:41 +02001931 mStatusBarView.setFocusable(false);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01001932
1933 visibilityChanged(true);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07001934 mWaitingForKeyguardExit = false;
Jorim Jaggi2580a9762014-06-25 03:08:25 +02001935 disable(mDisabledUnmodified, !force /* animate */);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01001936 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
1937 }
1938
Daniel Sandler11cf1782012-09-27 14:03:08 -04001939 public void animateCollapsePanels() {
1940 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001941 }
1942
John Spurlockaf8d6c42014-05-07 17:49:08 -04001943 private final Runnable mAnimateCollapsePanels = new Runnable() {
1944 @Override
1945 public void run() {
1946 animateCollapsePanels();
1947 }
1948 };
1949
1950 public void postAnimateCollapsePanels() {
1951 mHandler.post(mAnimateCollapsePanels);
1952 }
1953
Daniel Sandler11cf1782012-09-27 14:03:08 -04001954 public void animateCollapsePanels(int flags) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -07001955 animateCollapsePanels(flags, false /* force */, false /* delayed */);
Jorim Jaggi34250762014-07-03 23:51:19 +02001956 }
1957
1958 public void animateCollapsePanels(int flags, boolean force) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -07001959 animateCollapsePanels(flags, force, false /* delayed*/);
1960 }
1961
1962 public void animateCollapsePanels(int flags, boolean force, boolean delayed) {
Jorim Jaggi34250762014-07-03 23:51:19 +02001963 if (!force &&
1964 (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001965 runPostCollapseRunnables();
Jorim Jaggic1cf1ae2014-05-02 21:19:17 +02001966 return;
1967 }
Joe Onorato808182d2010-07-09 18:52:06 -04001968 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04001969 Log.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04001970 + " mExpandedVisible=" + mExpandedVisible
Jim Miller9a720f52012-05-30 03:19:43 -07001971 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04001972 }
1973
Jim Miller9a720f52012-05-30 03:19:43 -07001974 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Winson Chungcdcd4872014-08-05 18:00:13 -07001975 if (!mHandler.hasMessages(MSG_HIDE_RECENT_APPS)) {
1976 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
1977 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
1978 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07001979 }
Jim Miller9a720f52012-05-30 03:19:43 -07001980
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001981 if (mStatusBarWindow != null) {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001982 // release focus immediately to kick off focus change transition
1983 mStatusBarWindowManager.setStatusBarFocusable(false);
1984
John Spurlockab847cf2014-01-15 14:13:59 -05001985 mStatusBarWindow.cancelExpandHelper();
Jorim Jaggi27c9b742015-04-09 10:34:49 -07001986 mStatusBarView.collapseAllPanels(true /* animate */, delayed);
John Spurlockab847cf2014-01-15 14:13:59 -05001987 }
Joe Onorato808182d2010-07-09 18:52:06 -04001988 }
1989
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001990 private void runPostCollapseRunnables() {
1991 int size = mPostCollapseRunnables.size();
1992 for (int i = 0; i < size; i++) {
1993 mPostCollapseRunnables.get(i).run();
1994 }
1995 mPostCollapseRunnables.clear();
1996 }
1997
John Spurlockaf8d6c42014-05-07 17:49:08 -04001998 Animator mScrollViewAnim, mClearButtonAnim;
Daniel Sandler101784e2012-10-15 13:39:38 -04001999
Daniel Sandler08d05e32012-08-08 16:39:54 -04002000 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04002001 public void animateExpandNotificationsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04002002 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002003 if (!panelsEnabled()) {
Joe Onorato808182d2010-07-09 18:52:06 -04002004 return ;
2005 }
Joe Onorato808182d2010-07-09 18:52:06 -04002006
Daniel Sandler08d05e32012-08-08 16:39:54 -04002007 mNotificationPanel.expand();
Joe Onorato808182d2010-07-09 18:52:06 -04002008
2009 if (false) postStartTracing();
2010 }
2011
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002012 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04002013 public void animateExpandSettingsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04002014 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002015 if (!panelsEnabled()) {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002016 return;
2017 }
2018
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05002019 // Settings are not available in setup
2020 if (!mUserSetup) return;
2021
Jason Monk3c68ca22015-01-30 11:30:29 -05002022 mNotificationPanel.expandWithQs();
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002023
2024 if (false) postStartTracing();
2025 }
2026
2027 public void animateCollapseQuickSettings() {
Jorim Jaggi449981b2014-10-03 14:24:55 -07002028 if (mState == StatusBarState.SHADE) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002029 mStatusBarView.collapseAllPanels(true, false /* delayed */);
Jorim Jaggi449981b2014-10-03 14:24:55 -07002030 }
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002031 }
2032
Daniel Sandler08d05e32012-08-08 16:39:54 -04002033 void makeExpandedInvisible() {
John Spurlockcd686b52013-06-05 10:13:46 -04002034 if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04002035 + " mExpandedVisible=" + mExpandedVisible);
2036
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002037 if (!mExpandedVisible || mStatusBarWindow == null) {
Joe Onorato808182d2010-07-09 18:52:06 -04002038 return;
2039 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002040
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04002041 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002042 mStatusBarView.collapseAllPanels(/*animate=*/ false, false /* delayed*/);
Daniel Sandlered930e52012-07-03 14:31:22 -04002043
Jorim Jaggid7daab72014-05-06 22:22:20 +02002044 mNotificationPanel.closeQs();
Daniel Sandler040c2e42012-10-17 00:56:33 -04002045
Joe Onorato808182d2010-07-09 18:52:06 -04002046 mExpandedVisible = false;
John Spurlockd5ef5462012-06-13 11:19:51 -04002047 if (mNavigationBarView != null)
2048 mNavigationBarView.setSlippery(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002049 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04002050
2051 // Shrink the window to the size of the status bar only
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002052 mStatusBarWindowManager.setStatusBarExpanded(false);
Selim Cineke32010a2014-08-20 23:50:41 +02002053 mStatusBarView.setFocusable(true);
Joe Onorato808182d2010-07-09 18:52:06 -04002054
Daniel Sandler469e96e2012-05-04 15:56:19 -04002055 // Close any "App info" popups that might have snuck on-screen
2056 dismissPopups();
2057
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002058 runPostCollapseRunnables();
John Spurlockcfc359a2013-09-05 10:42:03 -04002059 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002060 showBouncer();
Jorim Jaggi2580a9762014-06-25 03:08:25 +02002061 disable(mDisabledUnmodified, true /* animate */);
Jorim Jaggi786afcb2014-09-25 02:41:29 +02002062
2063 // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in
2064 // the bouncer appear animation.
2065 if (!mStatusBarKeyguardViewManager.isShowing()) {
2066 WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
2067 }
Joe Onorato808182d2010-07-09 18:52:06 -04002068 }
2069
Daniel Sandlerb17a7262012-10-05 14:32:50 -04002070 public boolean interceptTouchEvent(MotionEvent event) {
Chris Wren64161cc2012-12-17 16:49:30 -05002071 if (DEBUG_GESTURES) {
2072 if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
2073 EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
2074 event.getActionMasked(), (int) event.getX(), (int) event.getY(), mDisabled);
2075 }
2076
2077 }
2078
Joe Onorato808182d2010-07-09 18:52:06 -04002079 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04002080 Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
John Spurlock804df702012-06-01 15:34:27 -04002081 + mDisabled + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002082 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002083 if (event.getAction() != MotionEvent.ACTION_MOVE) {
John Spurlockcd686b52013-06-05 10:13:46 -04002084 Log.d(TAG, String.format(
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002085 "panel: %s at (%f, %f) mDisabled=0x%08x",
2086 MotionEvent.actionToString(event.getAction()),
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002087 event.getRawX(), event.getRawY(), mDisabled));
2088 }
Joe Onorato808182d2010-07-09 18:52:06 -04002089 }
2090
Daniel Sandler151f00d2012-10-02 22:33:08 -04002091 if (DEBUG_GESTURES) {
2092 mGestureRec.add(event);
2093 }
Daniel Sandler33805342012-07-23 15:45:12 -04002094
John Spurlock686820a2013-09-03 14:44:16 -04002095 if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
John Spurlock5fee8362013-09-12 10:34:33 -04002096 final boolean upOrCancel =
2097 event.getAction() == MotionEvent.ACTION_UP ||
2098 event.getAction() == MotionEvent.ACTION_CANCEL;
2099 if (upOrCancel && !mExpandedVisible) {
2100 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
2101 } else {
2102 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2103 }
John Spurlock686820a2013-09-03 14:44:16 -04002104 }
Joe Onorato808182d2010-07-09 18:52:06 -04002105 return false;
2106 }
2107
Daniel Sandler08d05e32012-08-08 16:39:54 -04002108 public GestureRecorder getGestureRecorder() {
2109 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07002110 }
2111
John Spurlock56d007b2013-10-28 18:40:56 -04002112 private void setNavigationIconHints(int hints) {
Daniel Sandler328310c2011-09-23 15:56:52 -04002113 if (hints == mNavigationIconHints) return;
2114
2115 mNavigationIconHints = hints;
2116
2117 if (mNavigationBarView != null) {
2118 mNavigationBarView.setNavigationIconHints(hints);
2119 }
John Spurlockd4e65752013-08-28 14:17:09 -04002120 checkBarModes();
Daniel Sandler328310c2011-09-23 15:56:52 -04002121 }
2122
2123 @Override // CommandQueue
John Spurlock97642182013-07-29 17:58:39 -04002124 public void setWindowState(int window, int state) {
John Spurlockd4e65752013-08-28 14:17:09 -04002125 boolean showing = state == WINDOW_STATE_SHOWING;
John Spurlock97642182013-07-29 17:58:39 -04002126 if (mStatusBarWindow != null
2127 && window == StatusBarManager.WINDOW_STATUS_BAR
2128 && mStatusBarWindowState != state) {
2129 mStatusBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002130 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
Jorim Jaggi449981b2014-10-03 14:24:55 -07002131 if (!showing && mState == StatusBarState.SHADE) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002132 mStatusBarView.collapseAllPanels(false /* animate */, false /* delayed */);
John Spurlock97642182013-07-29 17:58:39 -04002133 }
2134 }
2135 if (mNavigationBarView != null
2136 && window == StatusBarManager.WINDOW_NAVIGATION_BAR
2137 && mNavigationBarWindowState != state) {
2138 mNavigationBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002139 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
John Spurlock97642182013-07-29 17:58:39 -04002140 }
2141 }
2142
John Spurlock97642182013-07-29 17:58:39 -04002143 @Override // CommandQueue
John Spurlockcad57682014-07-26 17:09:56 -04002144 public void buzzBeepBlinked() {
2145 if (mDozeServiceHost != null) {
2146 mDozeServiceHost.fireBuzzBeepBlinked();
2147 }
2148 }
2149
John Spurlockcb566aa2014-08-03 22:58:28 -04002150 @Override
2151 public void notificationLightOff() {
2152 if (mDozeServiceHost != null) {
2153 mDozeServiceHost.fireNotificationLight(false);
2154 }
2155 }
2156
2157 @Override
2158 public void notificationLightPulse(int argb, int onMillis, int offMillis) {
2159 if (mDozeServiceHost != null) {
2160 mDozeServiceHost.fireNotificationLight(true);
2161 }
2162 }
2163
John Spurlockcad57682014-07-26 17:09:56 -04002164 @Override // CommandQueue
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002165 public void setSystemUiVisibility(int vis, int mask) {
2166 final int oldVal = mSystemUiVisibility;
2167 final int newVal = (oldVal&~mask) | (vis&mask);
2168 final int diff = newVal ^ oldVal;
John Spurlockcd686b52013-06-05 10:13:46 -04002169 if (DEBUG) Log.d(TAG, String.format(
John Spurlockdcf4f212013-05-21 17:19:53 -04002170 "setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",
2171 Integer.toHexString(vis), Integer.toHexString(mask),
2172 Integer.toHexString(oldVal), Integer.toHexString(newVal),
2173 Integer.toHexString(diff)));
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002174 if (diff != 0) {
Winson Chung9214eff2014-06-12 13:59:25 -07002175 // we never set the recents bit via this method, so save the prior state to prevent
2176 // clobbering the bit below
2177 final boolean wasRecentsVisible = (mSystemUiVisibility & View.RECENT_APPS_VISIBLE) > 0;
2178
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002179 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04002180
John Spurlocke1f366f2013-08-05 12:22:40 -04002181 // update low profile
2182 if ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
2183 final boolean lightsOut = (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002184 if (lightsOut) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002185 animateCollapsePanels();
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002186 }
Jim Millera073e572012-05-23 17:03:27 -07002187
John Spurlock7edfbca2013-09-14 11:58:55 -04002188 setAreThereNotifications();
Daniel Sandler60ee2562011-07-22 12:34:33 -04002189 }
2190
John Spurlocke1f366f2013-08-05 12:22:40 -04002191 // update status bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04002192 final int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
John Spurlockbd957402013-10-03 11:38:39 -04002193 View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT);
John Spurlocke1f366f2013-08-05 12:22:40 -04002194
2195 // update navigation bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04002196 final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
John Spurlockf6b63972013-08-27 16:08:28 -04002197 oldVal, newVal, mNavigationBarView.getBarTransitions(),
John Spurlockbd957402013-10-03 11:38:39 -04002198 View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT);
John Spurlockd4e65752013-08-28 14:17:09 -04002199 final boolean sbModeChanged = sbMode != -1;
2200 final boolean nbModeChanged = nbMode != -1;
2201 boolean checkBarModes = false;
2202 if (sbModeChanged && sbMode != mStatusBarMode) {
2203 mStatusBarMode = sbMode;
2204 checkBarModes = true;
2205 }
2206 if (nbModeChanged && nbMode != mNavigationBarMode) {
2207 mNavigationBarMode = nbMode;
2208 checkBarModes = true;
2209 }
2210 if (checkBarModes) {
2211 checkBarModes();
2212 }
2213 if (sbModeChanged || nbModeChanged) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002214 // update transient bar autohide
John Spurlockc6d1c602014-01-17 15:22:06 -05002215 if (mStatusBarMode == MODE_SEMI_TRANSPARENT || mNavigationBarMode == MODE_SEMI_TRANSPARENT) {
John Spurlock32beb2c2013-03-11 10:16:47 -04002216 scheduleAutohide();
2217 } else {
John Spurlock32beb2c2013-03-11 10:16:47 -04002218 cancelAutohide();
2219 }
2220 }
John Spurlocke1f366f2013-08-05 12:22:40 -04002221
John Spurlock5b9145b2013-08-20 15:13:47 -04002222 // ready to unhide
2223 if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
2224 mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
2225 }
2226 if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
2227 mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
2228 }
2229
Adrian Roos75fa3852015-01-27 20:21:44 +01002230 if ((diff & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0 || sbModeChanged) {
Adrian Roos761c1562015-02-04 14:35:23 +01002231 boolean isTransparentBar = (mStatusBarMode == MODE_TRANSPARENT
2232 || mStatusBarMode == MODE_LIGHTS_OUT_TRANSPARENT);
2233 boolean allowLight = isTransparentBar && !mBatteryController.isPowerSave();
Adrian Roos75fa3852015-01-27 20:21:44 +01002234 boolean light = (vis & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0;
2235
Jorim Jaggi5443cc52015-03-20 14:39:24 -07002236 mIconController.setIconsDark(allowLight && light);
Adrian Roos75fa3852015-01-27 20:21:44 +01002237 }
Winson Chung9214eff2014-06-12 13:59:25 -07002238 // restore the recents bit
2239 if (wasRecentsVisible) {
2240 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
2241 }
2242
John Spurlocke1f366f2013-08-05 12:22:40 -04002243 // send updated sysui visibility to window manager
John Spurlock32beb2c2013-03-11 10:16:47 -04002244 notifyUiVisibilityChanged(mSystemUiVisibility);
Joe Onorato93056472010-09-10 10:30:46 -04002245 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002246 }
2247
John Spurlockd4e65752013-08-28 14:17:09 -04002248 private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
John Spurlockbd957402013-10-03 11:38:39 -04002249 int transientFlag, int translucentFlag) {
2250 final int oldMode = barMode(oldVis, transientFlag, translucentFlag);
2251 final int newMode = barMode(newVis, transientFlag, translucentFlag);
John Spurlocke1f366f2013-08-05 12:22:40 -04002252 if (oldMode == newMode) {
2253 return -1; // no mode change
2254 }
John Spurlocke1f366f2013-08-05 12:22:40 -04002255 return newMode;
2256 }
2257
John Spurlockbd957402013-10-03 11:38:39 -04002258 private int barMode(int vis, int transientFlag, int translucentFlag) {
Adrian Roosc0f0a742014-10-28 16:39:56 +01002259 int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_TRANSPARENT;
John Spurlock89835dd2013-08-16 15:06:51 -04002260 return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
John Spurlockbd957402013-10-03 11:38:39 -04002261 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
Adrian Roosc0f0a742014-10-28 16:39:56 +01002262 : (vis & lightsOutTransparent) == lightsOutTransparent ? MODE_LIGHTS_OUT_TRANSPARENT
Adrian Roosea562512014-05-05 13:33:03 +02002263 : (vis & View.SYSTEM_UI_TRANSPARENT) != 0 ? MODE_TRANSPARENT
John Spurlock7edfbca2013-09-14 11:58:55 -04002264 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
John Spurlock3b139a92013-08-17 17:18:08 -04002265 : MODE_OPAQUE;
John Spurlocke1f366f2013-08-05 12:22:40 -04002266 }
2267
John Spurlockd4e65752013-08-28 14:17:09 -04002268 private void checkBarModes() {
John Spurlock3c875662013-08-31 15:07:25 -04002269 if (mDemoMode) return;
Jorim Jaggi28d22d02014-05-10 03:37:04 +02002270 checkBarMode(mStatusBarMode, mStatusBarWindowState, mStatusBarView.getBarTransitions());
John Spurlockd4e65752013-08-28 14:17:09 -04002271 if (mNavigationBarView != null) {
2272 checkBarMode(mNavigationBarMode,
2273 mNavigationBarWindowState, mNavigationBarView.getBarTransitions());
2274 }
2275 }
2276
2277 private void checkBarMode(int mode, int windowState, BarTransitions transitions) {
John Spurlock0ff62e02014-07-22 16:15:08 -04002278 final boolean powerSave = mBatteryController.isPowerSave();
2279 final boolean anim = (mScreenOn == null || mScreenOn) && windowState != WINDOW_STATE_HIDDEN
2280 && !powerSave;
John Spurlock1bb480a2014-08-02 17:12:43 -04002281 if (powerSave && getBarState() == StatusBarState.SHADE) {
John Spurlock0ff62e02014-07-22 16:15:08 -04002282 mode = MODE_WARNING;
2283 }
John Spurlockc68d5772013-10-08 11:47:58 -04002284 transitions.transitionTo(mode, anim);
John Spurlockd4e65752013-08-28 14:17:09 -04002285 }
2286
John Spurlock42197262013-10-21 09:32:25 -04002287 private void finishBarAnimations() {
2288 mStatusBarView.getBarTransitions().finishAnimations();
2289 if (mNavigationBarView != null) {
2290 mNavigationBarView.getBarTransitions().finishAnimations();
2291 }
2292 }
2293
John Spurlockd4e65752013-08-28 14:17:09 -04002294 private final Runnable mCheckBarModes = new Runnable() {
John Spurlock5b9145b2013-08-20 15:13:47 -04002295 @Override
2296 public void run() {
John Spurlockd4e65752013-08-28 14:17:09 -04002297 checkBarModes();
John Spurlock0ff62e02014-07-22 16:15:08 -04002298 }
2299 };
John Spurlock5b9145b2013-08-20 15:13:47 -04002300
John Spurlockad3e6cb2013-04-30 08:47:43 -04002301 @Override
John Spurlockcfc359a2013-09-05 10:42:03 -04002302 public void setInteracting(int barWindow, boolean interacting) {
John Spurlock7fbf5732014-11-18 11:40:22 -05002303 final boolean changing = ((mInteractingWindows & barWindow) != 0) != interacting;
John Spurlockcfc359a2013-09-05 10:42:03 -04002304 mInteractingWindows = interacting
2305 ? (mInteractingWindows | barWindow)
2306 : (mInteractingWindows & ~barWindow);
2307 if (mInteractingWindows != 0) {
John Spurlockd4e65752013-08-28 14:17:09 -04002308 suspendAutohide();
2309 } else {
2310 resumeSuspendedAutohide();
2311 }
John Spurlock7fbf5732014-11-18 11:40:22 -05002312 // manually dismiss the volume panel when interacting with the nav bar
2313 if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) {
2314 if (mVolumeComponent != null) {
2315 mVolumeComponent.dismissNow();
2316 }
2317 }
John Spurlockd4e65752013-08-28 14:17:09 -04002318 checkBarModes();
2319 }
2320
2321 private void resumeSuspendedAutohide() {
John Spurlockad3e6cb2013-04-30 08:47:43 -04002322 if (mAutohideSuspended) {
2323 scheduleAutohide();
John Spurlockd4e65752013-08-28 14:17:09 -04002324 mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher
John Spurlock3b139a92013-08-17 17:18:08 -04002325 }
2326 }
2327
John Spurlockd4e65752013-08-28 14:17:09 -04002328 private void suspendAutohide() {
John Spurlock32beb2c2013-03-11 10:16:47 -04002329 mHandler.removeCallbacks(mAutohide);
John Spurlockd4e65752013-08-28 14:17:09 -04002330 mHandler.removeCallbacks(mCheckBarModes);
John Spurlock5b9145b2013-08-20 15:13:47 -04002331 mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
John Spurlock32beb2c2013-03-11 10:16:47 -04002332 }
2333
2334 private void cancelAutohide() {
2335 mAutohideSuspended = false;
2336 mHandler.removeCallbacks(mAutohide);
2337 }
2338
2339 private void scheduleAutohide() {
2340 cancelAutohide();
2341 mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
2342 }
2343
John Spurlock9deaa282013-07-25 13:03:47 -04002344 private void checkUserAutohide(View v, MotionEvent event) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002345 if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
John Spurlock9deaa282013-07-25 13:03:47 -04002346 && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
2347 && event.getX() == 0 && event.getY() == 0 // a touch outside both bars
2348 ) {
2349 userAutohide();
2350 }
2351 }
2352
2353 private void userAutohide() {
2354 cancelAutohide();
John Spurlock5b9145b2013-08-20 15:13:47 -04002355 mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
John Spurlock9deaa282013-07-25 13:03:47 -04002356 }
2357
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002358 private boolean areLightsOn() {
2359 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
2360 }
Jim Millera073e572012-05-23 17:03:27 -07002361
Daniel Sandler60ee2562011-07-22 12:34:33 -04002362 public void setLightsOn(boolean on) {
2363 Log.v(TAG, "setLightsOn(" + on + ")");
2364 if (on) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002365 setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002366 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002367 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002368 }
2369 }
2370
John Spurlock32beb2c2013-03-11 10:16:47 -04002371 private void notifyUiVisibilityChanged(int vis) {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002372 try {
John Spurlock32beb2c2013-03-11 10:16:47 -04002373 mWindowManagerService.statusBarVisibilityChanged(vis);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002374 } catch (RemoteException ex) {
2375 }
Joe Onorato93056472010-09-10 10:30:46 -04002376 }
2377
Daniel Sandler5c8da942011-06-28 00:29:04 -04002378 public void topAppWindowChanged(boolean showMenu) {
2379 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04002380 Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
Daniel Sandler5c8da942011-06-28 00:29:04 -04002381 }
2382 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04002383 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04002384 }
2385
2386 // See above re: lights-out policy for legacy apps.
2387 if (showMenu) setLightsOn(true);
2388 }
2389
Daniel Sandler328310c2011-09-23 15:56:52 -04002390 @Override
Jason Monkb605fec2014-05-02 17:04:10 -04002391 public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
2392 boolean showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04002393 boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
2394 int flags = mNavigationIconHints;
2395 if ((backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS) || imeShown) {
2396 flags |= NAVIGATION_HINT_BACK_ALT;
2397 } else {
2398 flags &= ~NAVIGATION_HINT_BACK_ALT;
2399 }
Jason Monkb605fec2014-05-02 17:04:10 -04002400 if (showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04002401 flags |= NAVIGATION_HINT_IME_SHOWN;
2402 } else {
2403 flags &= ~NAVIGATION_HINT_IME_SHOWN;
2404 }
Daniel Sandler328310c2011-09-23 15:56:52 -04002405
Jason Monkf1ff2092014-04-29 16:50:53 -04002406 setNavigationIconHints(flags);
Daniel Sandler328310c2011-09-23 15:56:52 -04002407 }
2408
Daniel Sandler48852952011-12-01 14:34:23 -05002409 public static String viewInfo(View v) {
2410 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
2411 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04002412 }
2413
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002414 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04002415 synchronized (mQueueLock) {
2416 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002417 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04002418 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04002419 pw.println(" mTracking=" + mTracking);
Daniel Sandler36412a72011-08-04 09:35:13 -04002420 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Selim Cinekb6d85eb2014-03-28 20:21:01 +01002421 pw.println(" mStackScroller: " + viewInfo(mStackScroller));
Selim Cinekb6d85eb2014-03-28 20:21:01 +01002422 pw.println(" mStackScroller: " + viewInfo(mStackScroller)
2423 + " scroll " + mStackScroller.getScrollX()
2424 + "," + mStackScroller.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04002425 }
Joe Onorato808182d2010-07-09 18:52:06 -04002426
John Spurlockcfc359a2013-09-05 10:42:03 -04002427 pw.print(" mInteractingWindows="); pw.println(mInteractingWindows);
John Spurlock0ec64c62013-08-26 15:37:58 -04002428 pw.print(" mStatusBarWindowState=");
2429 pw.println(windowStateToString(mStatusBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002430 pw.print(" mStatusBarMode=");
2431 pw.println(BarTransitions.modeToString(mStatusBarMode));
John Spurlockbf370992014-06-17 13:58:31 -04002432 pw.print(" mDozing="); pw.println(mDozing);
John Spurlocke677d712014-02-13 12:52:19 -05002433 pw.print(" mZenMode=");
2434 pw.println(Settings.Global.zenModeToString(mZenMode));
Chris Wren3b6745b2014-03-07 14:34:35 -05002435 pw.print(" mUseHeadsUp=");
2436 pw.println(mUseHeadsUp);
John Spurlock0ec64c62013-08-26 15:37:58 -04002437 dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
2438 if (mNavigationBarView != null) {
2439 pw.print(" mNavigationBarWindowState=");
2440 pw.println(windowStateToString(mNavigationBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002441 pw.print(" mNavigationBarMode=");
2442 pw.println(BarTransitions.modeToString(mNavigationBarMode));
John Spurlock0ec64c62013-08-26 15:37:58 -04002443 dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
2444 }
2445
Daniel Sandler48852952011-12-01 14:34:23 -05002446 pw.print(" mNavigationBarView=");
2447 if (mNavigationBarView == null) {
2448 pw.println("null");
2449 } else {
2450 mNavigationBarView.dump(fd, pw, args);
2451 }
2452
Dan Sandler16128f42014-05-21 12:48:22 -04002453 pw.print(" mMediaSessionManager=");
2454 pw.println(mMediaSessionManager);
2455 pw.print(" mMediaNotificationKey=");
2456 pw.println(mMediaNotificationKey);
2457 pw.print(" mMediaController=");
2458 pw.print(mMediaController);
2459 if (mMediaController != null) {
2460 pw.print(" state=" + mMediaController.getPlaybackState());
2461 }
2462 pw.println();
2463 pw.print(" mMediaMetadata=");
2464 pw.print(mMediaMetadata);
2465 if (mMediaMetadata != null) {
RoboErik75847b92014-07-29 13:10:17 -07002466 pw.print(" title=" + mMediaMetadata.getText(MediaMetadata.METADATA_KEY_TITLE));
Dan Sandler16128f42014-05-21 12:48:22 -04002467 }
2468 pw.println();
2469
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002470 pw.println(" Panels: ");
2471 if (mNotificationPanel != null) {
2472 pw.println(" mNotificationPanel=" +
2473 mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""));
2474 pw.print (" ");
2475 mNotificationPanel.dump(fd, pw, args);
2476 }
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002477
John Spurlock813552c2014-09-19 08:30:21 -04002478 DozeLog.dump(pw);
2479
Daniel Sandler7579bca2011-08-18 15:47:26 -04002480 if (DUMPTRUCK) {
2481 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02002482 mNotificationData.dump(pw, " ");
Daniel Sandler7579bca2011-08-18 15:47:26 -04002483 }
2484
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002485 mIconController.dump(pw);
Jim Miller5e6af442011-12-02 18:24:26 -08002486
Daniel Sandler89d97132011-09-08 15:31:57 -04002487 if (false) {
2488 pw.println("see the logcat for a dump of the views we have created.");
2489 // must happen on ui thread
2490 mHandler.post(new Runnable() {
2491 public void run() {
2492 mStatusBarView.getLocationOnScreen(mAbsPos);
John Spurlockcd686b52013-06-05 10:13:46 -04002493 Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
Daniel Sandler89d97132011-09-08 15:31:57 -04002494 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04002495 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04002496 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04002497 }
2498 });
2499 }
Joe Onorato808182d2010-07-09 18:52:06 -04002500 }
Daniel Sandler89d97132011-09-08 15:31:57 -04002501
Daniel Sandler151f00d2012-10-02 22:33:08 -04002502 if (DEBUG_GESTURES) {
2503 pw.print(" status bar gestures: ");
2504 mGestureRec.dump(fd, pw, args);
2505 }
Daniel Sandler33805342012-07-23 15:45:12 -04002506
John Spurlock486b78e2014-07-07 08:37:56 -04002507 if (mNetworkController != null) {
2508 mNetworkController.dump(fd, pw, args);
2509 }
2510 if (mBluetoothController != null) {
2511 mBluetoothController.dump(fd, pw, args);
2512 }
John Spurlock1e6eb172014-07-13 11:59:50 -04002513 if (mCastController != null) {
2514 mCastController.dump(fd, pw, args);
2515 }
Adrian Roos00a0b1f2014-07-16 16:44:49 +02002516 if (mUserSwitcherController != null) {
2517 mUserSwitcherController.dump(fd, pw, args);
2518 }
John Spurlock0ff62e02014-07-22 16:15:08 -04002519 if (mBatteryController != null) {
2520 mBatteryController.dump(fd, pw, args);
2521 }
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02002522 if (mNextAlarmController != null) {
2523 mNextAlarmController.dump(fd, pw, args);
2524 }
Jason Monk3d5f5512014-07-25 11:17:28 -04002525 if (mSecurityController != null) {
2526 mSecurityController.dump(fd, pw, args);
2527 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002528 if (mHeadsUpManager != null) {
2529 mHeadsUpManager.dump(fd, pw, args);
Chris Wren428c6b62014-12-05 16:07:06 -05002530 } else {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002531 pw.println(" mHeadsUpManager: null");
Chris Wren428c6b62014-12-05 16:07:06 -05002532 }
2533
John Spurlock7bbb9f62014-10-21 12:15:28 -04002534 pw.println("SharedPreferences:");
Andrew Flynn82862572015-04-01 14:22:37 -04002535 for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
John Spurlock7bbb9f62014-10-21 12:15:28 -04002536 pw.print(" "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
2537 }
Joe Onorato808182d2010-07-09 18:52:06 -04002538 }
2539
Chris Wren3b6745b2014-03-07 14:34:35 -05002540 private String hunStateToString(Entry entry) {
2541 if (entry == null) return "null";
2542 if (entry.notification == null) return "corrupt";
2543 return entry.notification.getPackageName();
2544 }
2545
John Spurlock0ec64c62013-08-26 15:37:58 -04002546 private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
2547 pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
2548 pw.println(BarTransitions.modeToString(transitions.getMode()));
2549 }
2550
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002551 @Override
2552 public void createAndAddWindows() {
2553 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04002554 }
Jim Millere898ac52012-04-06 17:10:57 -07002555
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002556 private void addStatusBarWindow() {
Daniel Sandlera310af82012-04-24 01:20:13 -04002557 makeStatusBarView();
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002558 mStatusBarWindowManager = new StatusBarWindowManager(mContext);
2559 mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
Joe Onorato808182d2010-07-09 18:52:06 -04002560 }
2561
Daniel Sandler747a9e92012-08-10 16:39:19 -04002562 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002563 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04002564 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler7e8ae502013-10-10 23:38:19 -04002565 mDisplay.getSize(mCurrentDisplaySize);
Daniel Sandler151f00d2012-10-02 22:33:08 -04002566 if (DEBUG_GESTURES) {
John Spurlock209bede2013-07-17 12:23:27 -04002567 mGestureRec.tag("display",
Daniel Sandler151f00d2012-10-02 22:33:08 -04002568 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
2569 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002570 }
2571
Christoph Studerb0183992014-12-22 21:02:26 +01002572 float getDisplayDensity() {
2573 return mDisplayMetrics.density;
2574 }
2575
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002576 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02002577 final boolean dismissShade) {
Daniel Sandler3679bf52012-10-16 21:30:28 -04002578 if (onlyProvisioned && !isDeviceProvisioned()) return;
Adrian Roos4314f6d2014-05-28 14:10:27 +02002579
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02002580 final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
2581 mContext, intent, mCurrentUserId);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02002582 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Adrian Roos4314f6d2014-05-28 14:10:27 +02002583 dismissKeyguardThenExecute(new OnDismissAction() {
2584 @Override
2585 public boolean onDismiss() {
Selim Cinekbaa23272014-07-08 18:01:07 +02002586 AsyncTask.execute(new Runnable() {
2587 public void run() {
2588 try {
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02002589 if (keyguardShowing && !afterKeyguardGone) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002590 ActivityManagerNative.getDefault()
2591 .keyguardWaitingForActivityDrawn();
2592 }
Selim Cinekbaa23272014-07-08 18:01:07 +02002593 intent.setFlags(
2594 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
2595 mContext.startActivityAsUser(
2596 intent, new UserHandle(UserHandle.USER_CURRENT));
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02002597 overrideActivityPendingAppTransition(
2598 keyguardShowing && !afterKeyguardGone);
Selim Cinekbaa23272014-07-08 18:01:07 +02002599 } catch (RemoteException e) {
2600 }
2601 }
2602 });
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002603 if (dismissShade) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002604 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
2605 true /* delayed*/);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002606 }
2607 return true;
Adrian Roos4314f6d2014-05-28 14:10:27 +02002608 }
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02002609 }, afterKeyguardGone);
Daniel Sandler3679bf52012-10-16 21:30:28 -04002610 }
2611
Joe Onorato808182d2010-07-09 18:52:06 -04002612 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
2613 public void onReceive(Context context, Intent intent) {
John Spurlockcd686b52013-06-05 10:13:46 -04002614 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04002615 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04002616 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Kenny Guy44fc65f2014-11-28 22:18:14 +00002617 if (isCurrentProfile(getSendingUserId())) {
2618 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
2619 String reason = intent.getStringExtra("reason");
2620 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
2621 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
2622 }
2623 animateCollapsePanels(flags);
Michael Jurka3b1fc472011-06-13 10:54:40 -07002624 }
Joe Onorato808182d2010-07-09 18:52:06 -04002625 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002626 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
John Spurlocke631b412013-09-18 16:33:57 -04002627 mScreenOn = false;
John Spurlock1bbd49d2012-10-19 11:09:32 -04002628 notifyNavigationBarScreenOn(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002629 notifyHeadsUpScreenOff();
John Spurlock42197262013-10-21 09:32:25 -04002630 finishBarAnimations();
Selim Cinekccd14fb2014-08-12 18:53:24 +02002631 resetUserExpandedStates();
Daniel Sandlered930e52012-07-03 14:31:22 -04002632 }
Daniel Sandler7f3cf952012-08-31 14:57:09 -04002633 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
John Spurlocke631b412013-09-18 16:33:57 -04002634 mScreenOn = true;
John Spurlock1bbd49d2012-10-19 11:09:32 -04002635 notifyNavigationBarScreenOn(true);
Joe Onorato808182d2010-07-09 18:52:06 -04002636 }
John Spurlock3c875662013-08-31 15:07:25 -04002637 else if (ACTION_DEMO.equals(action)) {
2638 Bundle bundle = intent.getExtras();
2639 if (bundle != null) {
2640 String command = bundle.getString("command", "").trim().toLowerCase();
2641 if (command.length() > 0) {
2642 try {
2643 dispatchDemoCommand(command, bundle);
2644 } catch (Throwable t) {
2645 Log.w(TAG, "Error running demo command, intent=" + intent, t);
2646 }
2647 }
2648 }
Dan Sandler16128f42014-05-21 12:48:22 -04002649 } else if ("fake_artwork".equals(action)) {
2650 if (DEBUG_MEDIA_FAKE_ARTWORK) {
2651 updateMediaMetaData(true);
2652 }
John Spurlock3c875662013-08-31 15:07:25 -04002653 }
Joe Onorato808182d2010-07-09 18:52:06 -04002654 }
2655 };
2656
Selim Cinekccd14fb2014-08-12 18:53:24 +02002657 private void resetUserExpandedStates() {
2658 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
2659 final int notificationCount = activeNotifications.size();
2660 for (int i = 0; i < notificationCount; i++) {
2661 NotificationData.Entry entry = activeNotifications.get(i);
2662 if (entry.row != null) {
2663 entry.row.resetUserExpansion();
2664 }
2665 }
2666 }
2667
Adrian Roos7d7090d2014-05-21 13:10:23 +02002668 @Override
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02002669 protected void dismissKeyguardThenExecute(final OnDismissAction action,
2670 boolean afterKeyguardGone) {
Adrian Roos7d7090d2014-05-21 13:10:23 +02002671 if (mStatusBarKeyguardViewManager.isShowing()) {
Jorim Jaggid6f440e02014-11-10 19:27:54 +01002672 mStatusBarKeyguardViewManager.dismissWithAction(action, afterKeyguardGone);
Adrian Roos7d7090d2014-05-21 13:10:23 +02002673 } else {
2674 action.onDismiss();
2675 }
2676 }
2677
Daniel Sandler777dcde2013-09-30 10:21:45 -04002678 // SystemUIService notifies SystemBars of configuration changes, which then calls down here
2679 @Override
2680 protected void onConfigurationChanged(Configuration newConfig) {
2681 super.onConfigurationChanged(newConfig); // calls refreshLayout
2682
2683 if (DEBUG) {
2684 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
2685 }
Daniel Sandler7e8ae502013-10-10 23:38:19 -04002686 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler777dcde2013-09-30 10:21:45 -04002687
2688 updateResources();
2689 repositionNavigationBar();
Daniel Sandler777dcde2013-09-30 10:21:45 -04002690 updateShowSearchHoldoff();
Jorim Jaggif6411742014-08-05 17:10:43 +00002691 updateRowStates();
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002692 mIconController.updateResources();
Jason Monk18f99d92014-09-11 13:36:42 -04002693 mScreenPinningRequest.onConfigurationChanged();
Daniel Sandler777dcde2013-09-30 10:21:45 -04002694 }
2695
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002696 @Override
2697 public void userSwitched(int newUserId) {
Chris Wrena6d4fb62014-11-20 14:46:23 -05002698 super.userSwitched(newUserId);
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002699 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04002700 animateCollapsePanels();
Adrian Roos31b844b2014-11-21 13:55:09 +01002701 updatePublicMode();
Christoph Studer37fe6932014-05-26 13:10:30 +02002702 updateNotifications();
John Spurlock919adac2012-10-02 16:41:12 -04002703 resetUserSetupObserver();
John Spurlock89f060a2014-07-16 21:03:15 -04002704 setControllerUsers();
2705 }
2706
2707 private void setControllerUsers() {
2708 if (mZenModeController != null) {
2709 mZenModeController.setUserId(mCurrentUserId);
2710 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002711 }
John Spurlock919adac2012-10-02 16:41:12 -04002712
2713 private void resetUserSetupObserver() {
2714 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
2715 mUserSetupObserver.onChange(false);
2716 mContext.getContentResolver().registerContentObserver(
2717 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002718 mUserSetupObserver, mCurrentUserId);
John Spurlock919adac2012-10-02 16:41:12 -04002719 }
2720
Joe Onorato808182d2010-07-09 18:52:06 -04002721 /**
2722 * Reload some of our resources when the configuration changes.
2723 *
2724 * We don't reload everything when the configuration changes -- we probably
2725 * should, but getting that smooth is tough. Someday we'll fix that. In the
2726 * meantime, just update the things that we know change.
2727 */
2728 void updateResources() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04002729 // Update the quick setting tiles
John Spurlock7e6809a2014-08-06 16:03:14 -04002730 if (mQSPanel != null) {
2731 mQSPanel.updateResources();
2732 }
Winson Chungd63c59782012-09-05 17:34:41 -07002733
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002734 loadDimens();
John Spurlock7e6809a2014-08-06 16:03:14 -04002735
2736 if (mNotificationPanel != null) {
2737 mNotificationPanel.updateResources();
2738 }
Adrian Roos5fd872e2014-08-12 17:28:58 +02002739 if (mBrightnessMirrorController != null) {
2740 mBrightnessMirrorController.updateResources();
2741 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002742 }
Jim Miller5e6af442011-12-02 18:24:26 -08002743
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002744 protected void loadDimens() {
2745 final Resources res = mContext.getResources();
2746
2747 mNaturalBarHeight = res.getDimensionPixelSize(
2748 com.android.internal.R.dimen.status_bar_height);
2749
Joe Onorato808182d2010-07-09 18:52:06 -04002750 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
2751
Jorim Jaggife40f7d2014-04-28 15:20:04 +02002752 mRowMinHeight = res.getDimensionPixelSize(R.dimen.notification_min_height);
2753 mRowMaxHeight = res.getDimensionPixelSize(R.dimen.notification_max_height);
Chris Wren51c75102013-07-16 20:49:17 -04002754
Jorim Jaggid4a57442014-04-10 02:45:55 +02002755 mKeyguardMaxNotificationCount = res.getInteger(R.integer.keyguard_max_notification_count);
2756
John Spurlock7e6809a2014-08-06 16:03:14 -04002757 if (DEBUG) Log.v(TAG, "updateResources");
John Spurlock804df702012-06-01 15:34:27 -04002758 }
2759
Christoph Studer92b389d2014-04-01 18:44:40 +02002760 // Visibility reporting
2761
2762 @Override
Christoph Studere8e28652014-10-29 17:27:53 +01002763 protected void handleVisibleToUserChanged(boolean visibleToUser) {
2764 if (visibleToUser) {
2765 super.handleVisibleToUserChanged(visibleToUser);
2766 startNotificationLogging();
Christoph Studer92b389d2014-04-01 18:44:40 +02002767 } else {
Christoph Studer037e34c2014-04-30 20:06:04 +02002768 stopNotificationLogging();
Christoph Studere8e28652014-10-29 17:27:53 +01002769 super.handleVisibleToUserChanged(visibleToUser);
Christoph Studer92b389d2014-04-01 18:44:40 +02002770 }
Christoph Studer92b389d2014-04-01 18:44:40 +02002771 }
2772
Christoph Studer037e34c2014-04-30 20:06:04 +02002773 private void stopNotificationLogging() {
2774 // Report all notifications as invisible and turn down the
2775 // reporter.
2776 if (!mCurrentlyVisibleNotifications.isEmpty()) {
2777 logNotificationVisibilityChanges(
2778 Collections.<String>emptyList(), mCurrentlyVisibleNotifications);
2779 mCurrentlyVisibleNotifications.clear();
2780 }
2781 mHandler.removeCallbacks(mVisibilityReporter);
2782 mStackScroller.setChildLocationsChangedListener(null);
2783 }
2784
Christoph Studere8e28652014-10-29 17:27:53 +01002785 private void startNotificationLogging() {
2786 mStackScroller.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
2787 // Some transitions like mVisibleToUser=false -> mVisibleToUser=true don't
2788 // cause the scroller to emit child location events. Hence generate
2789 // one ourselves to guarantee that we're reporting visible
2790 // notifications.
2791 // (Note that in cases where the scroller does emit events, this
2792 // additional event doesn't break anything.)
2793 mNotificationLocationsChangedListener.onChildLocationsChanged(mStackScroller);
Christoph Studer037e34c2014-04-30 20:06:04 +02002794 }
2795
Christoph Studer92b389d2014-04-01 18:44:40 +02002796 private void logNotificationVisibilityChanges(
2797 Collection<String> newlyVisible, Collection<String> noLongerVisible) {
2798 if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
2799 return;
2800 }
Christoph Studer92b389d2014-04-01 18:44:40 +02002801 String[] newlyVisibleAr = newlyVisible.toArray(new String[newlyVisible.size()]);
2802 String[] noLongerVisibleAr = noLongerVisible.toArray(new String[noLongerVisible.size()]);
2803 try {
2804 mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr);
2805 } catch (RemoteException e) {
2806 // Ignore.
2807 }
2808 }
2809
Christoph Studer2231c6e2014-12-19 12:40:13 +01002810 // State logging
2811
2812 private void logStateToEventlog() {
2813 boolean isShowing = mStatusBarKeyguardViewManager.isShowing();
2814 boolean isOccluded = mStatusBarKeyguardViewManager.isOccluded();
2815 boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing();
2816 boolean isSecure = mUnlockMethodCache.isMethodSecure();
2817 boolean isCurrentlyInsecure = mUnlockMethodCache.isCurrentlyInsecure();
2818 int stateFingerprint = getLoggingFingerprint(mState,
2819 isShowing,
2820 isOccluded,
2821 isBouncerShowing,
2822 isSecure,
2823 isCurrentlyInsecure);
2824 if (stateFingerprint != mLastLoggedStateFingerprint) {
2825 EventLogTags.writeSysuiStatusBarState(mState,
2826 isShowing ? 1 : 0,
2827 isOccluded ? 1 : 0,
2828 isBouncerShowing ? 1 : 0,
2829 isSecure ? 1 : 0,
2830 isCurrentlyInsecure ? 1 : 0);
2831 mLastLoggedStateFingerprint = stateFingerprint;
2832 }
2833 }
2834
2835 /**
2836 * Returns a fingerprint of fields logged to eventlog
2837 */
2838 private static int getLoggingFingerprint(int statusBarState, boolean keyguardShowing,
2839 boolean keyguardOccluded, boolean bouncerShowing, boolean secure,
2840 boolean currentlyInsecure) {
2841 // Reserve 8 bits for statusBarState. We'll never go higher than
2842 // that, right? Riiiight.
2843 return (statusBarState & 0xFF)
2844 | ((keyguardShowing ? 1 : 0) << 8)
2845 | ((keyguardOccluded ? 1 : 0) << 9)
2846 | ((bouncerShowing ? 1 : 0) << 10)
2847 | ((secure ? 1 : 0) << 11)
2848 | ((currentlyInsecure ? 1 : 0) << 12);
2849 }
2850
Joe Onorato808182d2010-07-09 18:52:06 -04002851 //
2852 // tracing
2853 //
2854
2855 void postStartTracing() {
2856 mHandler.postDelayed(mStartTracing, 3000);
2857 }
2858
2859 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002860 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
2861 Context.VIBRATOR_SERVICE);
John Spurlock7b414672014-07-18 13:02:39 -04002862 vib.vibrate(250, VIBRATION_ATTRIBUTES);
Joe Onorato808182d2010-07-09 18:52:06 -04002863 }
2864
2865 Runnable mStartTracing = new Runnable() {
2866 public void run() {
2867 vibrate();
2868 SystemClock.sleep(250);
John Spurlockcd686b52013-06-05 10:13:46 -04002869 Log.d(TAG, "startTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04002870 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
2871 mHandler.postDelayed(mStopTracing, 10000);
2872 }
2873 };
2874
2875 Runnable mStopTracing = new Runnable() {
2876 public void run() {
2877 android.os.Debug.stopMethodTracing();
John Spurlockcd686b52013-06-05 10:13:46 -04002878 Log.d(TAG, "stopTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04002879 vibrate();
2880 }
2881 };
Chris Wren0c8275b2012-05-08 13:36:48 -04002882
2883 @Override
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07002884 public boolean shouldDisableNavbarGestures() {
Daniel Sandlerd5483c32012-10-19 16:44:15 -04002885 return !isDeviceProvisioned()
2886 || mExpandedVisible
2887 || (mDisabled & StatusBarManager.DISABLE_SEARCH) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07002888 }
Joe Onorato808182d2010-07-09 18:52:06 -04002889
John Spurlockd47a3f32014-05-18 19:14:14 -04002890 public void postStartSettingsActivity(final Intent intent, int delay) {
2891 mHandler.postDelayed(new Runnable() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04002892 @Override
2893 public void run() {
2894 handleStartSettingsActivity(intent, true /*onlyProvisioned*/);
2895 }
John Spurlockd47a3f32014-05-18 19:14:14 -04002896 }, delay);
John Spurlockaf8d6c42014-05-07 17:49:08 -04002897 }
2898
2899 private void handleStartSettingsActivity(Intent intent, boolean onlyProvisioned) {
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02002900 startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
John Spurlockde547002014-02-28 17:50:39 -05002901 }
2902
Romain Guy648342f2012-05-25 10:44:45 -07002903 private static class FastColorDrawable extends Drawable {
2904 private final int mColor;
2905
2906 public FastColorDrawable(int color) {
2907 mColor = 0xff000000 | color;
2908 }
2909
2910 @Override
2911 public void draw(Canvas canvas) {
2912 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
2913 }
2914
2915 @Override
2916 public void setAlpha(int alpha) {
2917 }
2918
2919 @Override
Chris Craikbd3bfc52015-03-02 10:43:29 -08002920 public void setColorFilter(ColorFilter colorFilter) {
Romain Guy648342f2012-05-25 10:44:45 -07002921 }
2922
2923 @Override
2924 public int getOpacity() {
2925 return PixelFormat.OPAQUE;
2926 }
2927
2928 @Override
2929 public void setBounds(int left, int top, int right, int bottom) {
2930 }
2931
2932 @Override
2933 public void setBounds(Rect bounds) {
2934 }
2935 }
John Spurlock5c454122013-06-17 07:35:46 -04002936
2937 @Override
2938 public void destroy() {
2939 super.destroy();
2940 if (mStatusBarWindow != null) {
2941 mWindowManager.removeViewImmediate(mStatusBarWindow);
John Spurlockab847cf2014-01-15 14:13:59 -05002942 mStatusBarWindow = null;
John Spurlock5c454122013-06-17 07:35:46 -04002943 }
2944 if (mNavigationBarView != null) {
2945 mWindowManager.removeViewImmediate(mNavigationBarView);
John Spurlockab847cf2014-01-15 14:13:59 -05002946 mNavigationBarView = null;
John Spurlock5c454122013-06-17 07:35:46 -04002947 }
Jason Monk4ae97d32014-12-17 10:14:33 -05002948 if (mHandlerThread != null) {
2949 mHandlerThread.quitSafely();
2950 mHandlerThread = null;
2951 }
John Spurlock5c454122013-06-17 07:35:46 -04002952 mContext.unregisterReceiver(mBroadcastReceiver);
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07002953 mAssistGestureManager.destroy();
John Spurlock5c454122013-06-17 07:35:46 -04002954 }
John Spurlock3c875662013-08-31 15:07:25 -04002955
2956 private boolean mDemoModeAllowed;
2957 private boolean mDemoMode;
John Spurlock3c875662013-08-31 15:07:25 -04002958
2959 @Override
2960 public void dispatchDemoCommand(String command, Bundle args) {
2961 if (!mDemoModeAllowed) {
2962 mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
2963 "sysui_demo_allowed", 0) != 0;
2964 }
2965 if (!mDemoModeAllowed) return;
2966 if (command.equals(COMMAND_ENTER)) {
2967 mDemoMode = true;
2968 } else if (command.equals(COMMAND_EXIT)) {
2969 mDemoMode = false;
2970 checkBarModes();
2971 } else if (!mDemoMode) {
2972 // automatically enter demo mode on first demo command
2973 dispatchDemoCommand(COMMAND_ENTER, new Bundle());
2974 }
2975 boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
John Spurlockbb4a7022014-11-08 12:40:19 -05002976 if ((modeChange || command.equals(COMMAND_VOLUME)) && mVolumeComponent != null) {
2977 mVolumeComponent.dispatchDemoCommand(command, args);
2978 }
John Spurlock3c875662013-08-31 15:07:25 -04002979 if (modeChange || command.equals(COMMAND_CLOCK)) {
2980 dispatchDemoCommandToView(command, args, R.id.clock);
2981 }
2982 if (modeChange || command.equals(COMMAND_BATTERY)) {
2983 dispatchDemoCommandToView(command, args, R.id.battery);
2984 }
2985 if (modeChange || command.equals(COMMAND_STATUS)) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002986 mIconController.dispatchDemoCommand(command, args);
2987
John Spurlock3c875662013-08-31 15:07:25 -04002988 }
2989 if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
2990 mNetworkController.dispatchDemoCommand(command, args);
2991 }
John Spurlock7f42fc52014-01-14 16:20:39 -05002992 if (modeChange || command.equals(COMMAND_NOTIFICATIONS)) {
2993 View notifications = mStatusBarView == null ? null
2994 : mStatusBarView.findViewById(R.id.notification_icon_area);
2995 if (notifications != null) {
2996 String visible = args.getString("visible");
2997 int vis = mDemoMode && "false".equals(visible) ? View.INVISIBLE : View.VISIBLE;
2998 notifications.setVisibility(vis);
2999 }
3000 }
John Spurlock3c875662013-08-31 15:07:25 -04003001 if (command.equals(COMMAND_BARS)) {
3002 String mode = args.getString("mode");
3003 int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
John Spurlockbd957402013-10-03 11:38:39 -04003004 "translucent".equals(mode) ? MODE_TRANSLUCENT :
John Spurlock3c875662013-08-31 15:07:25 -04003005 "semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
John Spurlock0ff62e02014-07-22 16:15:08 -04003006 "transparent".equals(mode) ? MODE_TRANSPARENT :
3007 "warning".equals(mode) ? MODE_WARNING :
John Spurlock3c875662013-08-31 15:07:25 -04003008 -1;
3009 if (barMode != -1) {
3010 boolean animate = true;
3011 if (mStatusBarView != null) {
3012 mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
3013 }
3014 if (mNavigationBarView != null) {
3015 mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
3016 }
3017 }
3018 }
3019 }
3020
3021 private void dispatchDemoCommandToView(String command, Bundle args, int id) {
3022 if (mStatusBarView == null) return;
3023 View v = mStatusBarView.findViewById(id);
3024 if (v instanceof DemoMode) {
3025 ((DemoMode)v).dispatchDemoCommand(command, args);
3026 }
3027 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003028
Jorim Jaggiecbab362014-04-23 16:13:15 +02003029 /**
3030 * @return The {@link StatusBarState} the status bar is in.
3031 */
3032 public int getBarState() {
3033 return mState;
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003034 }
3035
3036 public void showKeyguard() {
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003037 if (mLaunchTransitionFadingAway) {
3038 mNotificationPanel.animate().cancel();
3039 mNotificationPanel.setAlpha(1f);
Jorim Jaggi826730a2014-12-08 21:05:13 +01003040 runLaunchTransitionEndRunnable();
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003041 mLaunchTransitionFadingAway = false;
3042 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01003043 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003044 setBarState(StatusBarState.KEYGUARD);
Jorim Jaggi98f85302014-08-07 17:45:04 +02003045 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggid41083a2014-09-12 02:54:40 +02003046 if (!mScreenOnFromKeyguard) {
3047
3048 // If the screen is off already, we need to disable touch events because these might
3049 // collapse the panel after we expanded it, and thus we would end up with a blank
3050 // Keyguard.
3051 mNotificationPanel.setTouchDisabled(true);
3052 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003053 instantExpandNotificationsPanel();
Jorim Jaggiecbab362014-04-23 16:13:15 +02003054 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003055 if (mDraggedDownRow != null) {
3056 mDraggedDownRow.setUserLocked(false);
Selim Cinekb5605e52015-02-20 18:21:41 +01003057 mDraggedDownRow.notifyHeightChanged(false /* needsAnimation */);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003058 mDraggedDownRow = null;
3059 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003060 }
3061
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003062 public boolean isCollapsing() {
3063 return mNotificationPanel.isCollapsing();
3064 }
3065
3066 public void addPostCollapseAction(Runnable r) {
3067 mPostCollapseRunnables.add(r);
3068 }
3069
Selim Cinekbaa23272014-07-08 18:01:07 +02003070 public boolean isInLaunchTransition() {
3071 return mNotificationPanel.isLaunchTransitionRunning()
3072 || mNotificationPanel.isLaunchTransitionFinished();
3073 }
3074
3075 /**
3076 * Fades the content of the keyguard away after the launch transition is done.
3077 *
3078 * @param beforeFading the runnable to be run when the circle is fully expanded and the fading
3079 * starts
3080 * @param endRunnable the runnable to be run when the transition is done
3081 */
3082 public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003083 Runnable endRunnable) {
Jorim Jaggi826730a2014-12-08 21:05:13 +01003084 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003085 mLaunchTransitionEndRunnable = endRunnable;
Selim Cinekbaa23272014-07-08 18:01:07 +02003086 Runnable hideRunnable = new Runnable() {
3087 @Override
3088 public void run() {
3089 mLaunchTransitionFadingAway = true;
3090 if (beforeFading != null) {
3091 beforeFading.run();
3092 }
3093 mNotificationPanel.setAlpha(1);
3094 mNotificationPanel.animate()
3095 .alpha(0)
3096 .setStartDelay(FADE_KEYGUARD_START_DELAY)
3097 .setDuration(FADE_KEYGUARD_DURATION)
3098 .withLayer()
3099 .withEndAction(new Runnable() {
3100 @Override
3101 public void run() {
3102 mNotificationPanel.setAlpha(1);
Jorim Jaggi826730a2014-12-08 21:05:13 +01003103 runLaunchTransitionEndRunnable();
Selim Cinekbaa23272014-07-08 18:01:07 +02003104 mLaunchTransitionFadingAway = false;
3105 }
3106 });
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003107 mIconController.appTransitionStarting(SystemClock.uptimeMillis(),
3108 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Selim Cinekbaa23272014-07-08 18:01:07 +02003109 }
3110 };
3111 if (mNotificationPanel.isLaunchTransitionRunning()) {
3112 mNotificationPanel.setLaunchTransitionEndRunnable(hideRunnable);
3113 } else {
3114 hideRunnable.run();
3115 }
3116 }
3117
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003118 /**
Jorim Jaggi826730a2014-12-08 21:05:13 +01003119 * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
3120 * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
3121 * because the launched app crashed or something else went wrong.
3122 */
3123 public void startLaunchTransitionTimeout() {
3124 mHandler.sendEmptyMessageDelayed(MSG_LAUNCH_TRANSITION_TIMEOUT,
3125 LAUNCH_TRANSITION_TIMEOUT_MS);
3126 }
3127
3128 private void onLaunchTransitionTimeout() {
3129 Log.w(TAG, "Launch transition: Timeout!");
3130 mNotificationPanel.resetViews();
3131 }
3132
3133 private void runLaunchTransitionEndRunnable() {
3134 if (mLaunchTransitionEndRunnable != null) {
3135 Runnable r = mLaunchTransitionEndRunnable;
3136
3137 // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
3138 // which would lead to infinite recursion. Protect against it.
3139 mLaunchTransitionEndRunnable = null;
3140 r.run();
3141 }
3142 }
3143
3144 /**
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003145 * @return true if we would like to stay in the shade, false if it should go away entirely
3146 */
3147 public boolean hideKeyguard() {
3148 boolean staying = mLeaveOpenOnKeyguardHide;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003149 setBarState(StatusBarState.SHADE);
3150 if (mLeaveOpenOnKeyguardHide) {
3151 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003152 mNotificationPanel.animateToFullShade(calculateGoingToFullShadeDelay());
3153 if (mDraggedDownRow != null) {
3154 mDraggedDownRow.setUserLocked(false);
3155 mDraggedDownRow = null;
3156 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003157 } else {
3158 instantCollapseNotificationPanel();
3159 }
Jorim Jaggi98f85302014-08-07 17:45:04 +02003160 updateKeyguardState(staying, false /* fromShadeLocked */);
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +01003161
3162 // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
3163 // visibilities so next time we open the panel we know the correct height already.
3164 if (mQSPanel != null) {
3165 mQSPanel.refreshAllTiles();
3166 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01003167 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003168 return staying;
3169 }
3170
3171 public long calculateGoingToFullShadeDelay() {
3172 return mKeyguardFadingAwayDelay + mKeyguardFadingAwayDuration;
Jorim Jaggi15682502014-04-23 12:01:36 +02003173 }
3174
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003175 /**
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003176 * Notifies the status bar that Keyguard is going away very soon.
3177 */
3178 public void keyguardGoingAway() {
3179
3180 // Treat Keyguard exit animation as an app transition to achieve nice transition for status
3181 // bar.
3182 mIconController.appTransitionPending();
3183 }
3184
3185 /**
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003186 * Notifies the status bar the Keyguard is fading away with the specified timings.
3187 *
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003188 * @param startTime the start time of the animations in uptime millis
3189 * @param delay the precalculated animation delay in miliseconds
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003190 * @param fadeoutDuration the duration of the exit animation, in milliseconds
3191 */
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003192 public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration) {
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003193 mKeyguardFadingAway = true;
3194 mKeyguardFadingAwayDelay = delay;
3195 mKeyguardFadingAwayDuration = fadeoutDuration;
3196 mWaitingForKeyguardExit = false;
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003197 mIconController.appTransitionStarting(
3198 startTime + fadeoutDuration
3199 - StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION,
3200 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Jorim Jaggi2580a9762014-06-25 03:08:25 +02003201 disable(mDisabledUnmodified, true /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003202 }
3203
Jorim Jaggi416493b2014-09-13 03:57:32 +02003204 public boolean isKeyguardFadingAway() {
3205 return mKeyguardFadingAway;
3206 }
3207
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003208 /**
3209 * Notifies that the Keyguard fading away animation is done.
3210 */
3211 public void finishKeyguardFadingAway() {
3212 mKeyguardFadingAway = false;
3213 }
3214
Jorim Jaggi15682502014-04-23 12:01:36 +02003215 private void updatePublicMode() {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003216 setLockscreenPublicMode(
3217 mStatusBarKeyguardViewManager.isShowing() && mStatusBarKeyguardViewManager
3218 .isSecure(mCurrentUserId));
Jorim Jaggi15682502014-04-23 12:01:36 +02003219 }
3220
Jorim Jaggi98f85302014-08-07 17:45:04 +02003221 private void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003222 if (mState == StatusBarState.KEYGUARD) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003223 mKeyguardIndicationController.setVisible(true);
Selim Cinek4c6969a2014-05-26 19:22:17 +02003224 mNotificationPanel.resetViews();
Jorim Jaggi98f85302014-08-07 17:45:04 +02003225 mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
Jorim Jaggi15682502014-04-23 12:01:36 +02003226 } else {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003227 mKeyguardIndicationController.setVisible(false);
Jorim Jaggi98f85302014-08-07 17:45:04 +02003228 mKeyguardUserSwitcher.setKeyguard(false,
3229 goingToFullShade || mState == StatusBarState.SHADE_LOCKED || fromShadeLocked);
Jorim Jaggi15682502014-04-23 12:01:36 +02003230 }
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003231 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02003232 mScrimController.setKeyguardShowing(true);
Kenny Guy3094d4a2015-04-01 19:14:10 +01003233 mIconPolicy.setKeyguardShowing(true);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003234 } else {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02003235 mScrimController.setKeyguardShowing(false);
Kenny Guy3094d4a2015-04-01 19:14:10 +01003236 mIconPolicy.setKeyguardShowing(false);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003237 }
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003238 mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
John Spurlockbf370992014-06-17 13:58:31 -04003239 updateDozingState();
Jorim Jaggi15682502014-04-23 12:01:36 +02003240 updatePublicMode();
Jorim Jaggiae441282014-08-01 02:45:18 +02003241 updateStackScrollerState(goingToFullShade);
Christoph Studer37fe6932014-05-26 13:10:30 +02003242 updateNotifications();
Jorim Jaggia6310292014-04-16 14:11:52 +02003243 checkBarModes();
Dan Sandler16128f42014-05-21 12:48:22 -04003244 updateMediaMetaData(false);
John Spurlock657c62c2014-07-22 12:18:09 -04003245 mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
3246 mStatusBarKeyguardViewManager.isSecure());
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003247 }
3248
John Spurlockbf370992014-06-17 13:58:31 -04003249 private void updateDozingState() {
John Spurlockcf5d3c92014-09-21 17:55:01 -04003250 if (mState != StatusBarState.KEYGUARD && !mNotificationPanel.isDozing()) {
Jorim Jaggi61d37f62014-07-30 17:26:55 +02003251 return;
3252 }
Jorim Jaggi4e857f42014-11-17 19:14:04 +01003253 boolean animate = !mDozing && mDozeScrimController.isPulsing();
3254 mNotificationPanel.setDozing(mDozing, animate);
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01003255 mStackScroller.setDark(mDozing, animate, mScreenOnTouchLocation);
Jorim Jaggi048af1f2014-11-11 22:51:10 +01003256 mScrimController.setDozing(mDozing);
Jorim Jaggi4e857f42014-11-17 19:14:04 +01003257 mDozeScrimController.setDozing(mDozing, animate);
John Spurlockbf370992014-06-17 13:58:31 -04003258 }
3259
Jorim Jaggiae441282014-08-01 02:45:18 +02003260 public void updateStackScrollerState(boolean goingToFullShade) {
John Spurlock4b3bda22014-05-22 14:32:20 -04003261 if (mStackScroller == null) return;
Selim Cinek1408eb52014-06-02 14:45:38 +02003262 boolean onKeyguard = mState == StatusBarState.KEYGUARD;
Jorim Jaggiae441282014-08-01 02:45:18 +02003263 mStackScroller.setHideSensitive(isLockscreenPublicMode(), goingToFullShade);
Selim Cinek1408eb52014-06-02 14:45:38 +02003264 mStackScroller.setDimmed(onKeyguard, false /* animate */);
Selim Cinek1408eb52014-06-02 14:45:38 +02003265 mStackScroller.setExpandingEnabled(!onKeyguard);
Selim Cineka32ab602014-06-11 15:06:01 +02003266 ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
3267 mStackScroller.setActivatedChild(null);
3268 if (activatedChild != null) {
3269 activatedChild.makeInactive(false /* animate */);
3270 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003271 }
3272
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003273 public void userActivity() {
Jorim Jaggib690f0d2014-07-03 23:25:44 +02003274 if (mState == StatusBarState.KEYGUARD) {
3275 mKeyguardViewMediatorCallback.userActivity();
3276 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003277 }
3278
Jorim Jaggidf993512014-05-13 23:06:35 +02003279 public boolean interceptMediaKey(KeyEvent event) {
3280 return mState == StatusBarState.KEYGUARD
3281 && mStatusBarKeyguardViewManager.interceptMediaKey(event);
3282 }
3283
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02003284 public boolean onMenuPressed() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003285 return mState == StatusBarState.KEYGUARD && mStatusBarKeyguardViewManager.onMenuPressed();
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02003286 }
3287
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003288 public boolean onBackPressed() {
Adrian Roos0002a452014-07-03 13:46:07 +02003289 if (mStatusBarKeyguardViewManager.onBackPressed()) {
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003290 return true;
3291 }
Adrian Roos0002a452014-07-03 13:46:07 +02003292 if (mNotificationPanel.isQsExpanded()) {
John Spurlockf7ae4422014-08-01 12:45:18 -04003293 if (mNotificationPanel.isQsDetailShowing()) {
3294 mNotificationPanel.closeQsDetail();
3295 } else {
3296 mNotificationPanel.animateCloseQs();
3297 }
Adrian Roos0002a452014-07-03 13:46:07 +02003298 return true;
3299 }
3300 if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) {
3301 animateCollapsePanels();
3302 return true;
3303 }
3304 return false;
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003305 }
3306
Jorim Jaggi34250762014-07-03 23:51:19 +02003307 public boolean onSpacePressed() {
Jorim Jaggi2c33d5d2014-08-29 16:28:20 +02003308 if (mScreenOn != null && mScreenOn
3309 && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
Jorim Jaggi4eedc1d2014-10-27 13:45:56 +01003310 animateCollapsePanels(
3311 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
Jorim Jaggi34250762014-07-03 23:51:19 +02003312 return true;
3313 }
3314 return false;
3315 }
3316
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003317 private void showBouncer() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003318 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekbaa23272014-07-08 18:01:07 +02003319 mWaitingForKeyguardExit = mStatusBarKeyguardViewManager.isShowing();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003320 mStatusBarKeyguardViewManager.dismiss();
3321 }
3322 }
3323
3324 private void instantExpandNotificationsPanel() {
Jorim Jaggic357ca22014-04-25 14:56:15 +02003325
Jorim Jaggi0a27be82014-06-11 03:22:39 +02003326 // Make our window larger and the panel expanded.
Jorim Jaggifa505a72014-04-28 20:04:11 +02003327 makeExpandedVisible(true);
Jorim Jaggi0a27be82014-06-11 03:22:39 +02003328 mNotificationPanel.instantExpand();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003329 }
Adrian Roos5a46cd32014-04-03 16:51:58 +02003330
Jorim Jaggia005f1b2014-04-16 19:06:10 +02003331 private void instantCollapseNotificationPanel() {
Selim Cinek6bb4a9b2014-10-09 17:48:05 -07003332 mNotificationPanel.instantCollapse();
Jorim Jaggia005f1b2014-04-16 19:06:10 +02003333 }
3334
Jorim Jaggid4a57442014-04-10 02:45:55 +02003335 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02003336 public void onActivated(ActivatableNotificationView view) {
Christoph Studerb0183992014-12-22 21:02:26 +01003337 EventLogTags.writeSysuiLockscreenGesture(
3338 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE,
3339 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
Adrian Roos12c1ef52014-06-04 13:54:08 +02003340 mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
Selim Cineka32ab602014-06-11 15:06:01 +02003341 ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
3342 if (previousView != null) {
3343 previousView.makeInactive(true /* animate */);
3344 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003345 mStackScroller.setActivatedChild(view);
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02003346 }
3347
Jorim Jaggiecbab362014-04-23 16:13:15 +02003348 /**
3349 * @param state The {@link StatusBarState} to set.
3350 */
3351 public void setBarState(int state) {
Christoph Studer2231c6e2014-12-19 12:40:13 +01003352 // If we're visible and switched to SHADE_LOCKED (the user dragged
3353 // down on the lockscreen), clear notification LED, vibration,
3354 // ringing.
3355 // Other transitions are covered in handleVisibleToUserChanged().
3356 if (state != mState && mVisible && state == StatusBarState.SHADE_LOCKED) {
3357 try {
3358 mBarService.clearNotificationEffects();
3359 } catch (RemoteException e) {
3360 // Ignore.
Christoph Studer1f32c652014-11-26 15:32:20 +01003361 }
3362 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003363 mState = state;
Selim Cinek25fd4e2b2015-02-20 17:46:07 +01003364 mGroupManager.setStatusBarState(state);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003365 mStatusBarWindowManager.setStatusBarState(state);
3366 }
3367
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02003368 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02003369 public void onActivationReset(ActivatableNotificationView view) {
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003370 if (view == mStackScroller.getActivatedChild()) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003371 mKeyguardIndicationController.hideTransientIndication();
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003372 mStackScroller.setActivatedChild(null);
3373 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02003374 }
3375
3376 public void onTrackingStarted() {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003377 runPostCollapseRunnables();
Jorim Jaggi90129582014-06-02 14:44:49 +02003378 }
3379
Selim Cinekdbbcfbe2014-10-24 17:52:35 +02003380 public void onClosingFinished() {
3381 runPostCollapseRunnables();
3382 }
3383
Jorim Jaggi90129582014-06-02 14:44:49 +02003384 public void onUnlockHintStarted() {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003385 mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
Jorim Jaggi90129582014-06-02 14:44:49 +02003386 }
3387
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02003388 public void onHintFinished() {
Jorim Jaggi93a2bb22014-06-02 19:57:28 +02003389 // Delay the reset a bit so the user can read the text.
Adrian Roos12c1ef52014-06-04 13:54:08 +02003390 mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
Jorim Jaggie70d31f2014-04-24 22:08:30 +02003391 }
3392
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02003393 public void onCameraHintStarted() {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003394 mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02003395 }
3396
3397 public void onPhoneHintStarted() {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003398 mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02003399 }
3400
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02003401 public void onTrackingStopped(boolean expand) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02003402 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Christoph Studer2231c6e2014-12-19 12:40:13 +01003403 if (!expand && !mUnlockMethodCache.isCurrentlyInsecure()) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02003404 showBouncer();
3405 }
3406 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02003407 }
3408
3409 @Override
Jorim Jaggid4a57442014-04-10 02:45:55 +02003410 protected int getMaxKeyguardNotifications() {
3411 return mKeyguardMaxNotificationCount;
3412 }
3413
Jorim Jaggia6310292014-04-16 14:11:52 +02003414 public NavigationBarView getNavigationBarView() {
3415 return mNavigationBarView;
3416 }
3417
Jorim Jaggiecbab362014-04-23 16:13:15 +02003418 // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
3419
3420 @Override
Christoph Studerb0183992014-12-22 21:02:26 +01003421 public boolean onDraggedDown(View startingChild, int dragLengthY) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02003422 if (hasActiveNotifications()) {
Christoph Studerb0183992014-12-22 21:02:26 +01003423 EventLogTags.writeSysuiLockscreenGesture(
3424 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE,
3425 (int) (dragLengthY / mDisplayMetrics.density),
3426 0 /* velocityDp - N/A */);
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02003427
3428 // We have notifications, go to locked shade.
3429 goToLockedShade(startingChild);
3430 return true;
3431 } else {
3432
3433 // No notifications - abort gesture.
3434 return false;
3435 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003436 }
3437
3438 @Override
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003439 public void onDragDownReset() {
3440 mStackScroller.setDimmed(true /* dimmed */, true /* animated */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003441 }
3442
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02003443 @Override
Jorim Jaggiecbab362014-04-23 16:13:15 +02003444 public void onThresholdReached() {
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003445 mStackScroller.setDimmed(false /* dimmed */, true /* animate */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003446 }
3447
Selim Cinek1408eb52014-06-02 14:45:38 +02003448 @Override
3449 public void onTouchSlopExceeded() {
3450 mStackScroller.removeLongPressCallback();
3451 }
3452
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02003453 @Override
3454 public void setEmptyDragAmount(float amount) {
3455 mNotificationPanel.setEmptyDragAmount(amount);
3456 }
3457
Jorim Jaggiecbab362014-04-23 16:13:15 +02003458 /**
3459 * If secure with redaction: Show bouncer, go to unlocked shade.
3460 *
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003461 * <p>If secure without redaction or no security: Go to {@link StatusBarState#SHADE_LOCKED}.</p>
Jorim Jaggiecbab362014-04-23 16:13:15 +02003462 *
3463 * @param expandView The view to expand after going to the shade.
3464 */
3465 public void goToLockedShade(View expandView) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003466 ExpandableNotificationRow row = null;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003467 if (expandView instanceof ExpandableNotificationRow) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003468 row = (ExpandableNotificationRow) expandView;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003469 row.setUserExpanded(true);
3470 }
Adrian Roosaee70462014-09-03 16:27:39 +02003471 boolean fullShadeNeedsBouncer = !userAllowsPrivateNotificationsInPublic(mCurrentUserId)
3472 || !mShowLockscreenNotifications;
3473 if (isLockscreenPublicMode() && fullShadeNeedsBouncer) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003474 mLeaveOpenOnKeyguardHide = true;
3475 showBouncer();
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003476 mDraggedDownRow = row;
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003477 } else {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003478 mNotificationPanel.animateToFullShade(0 /* delay */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003479 setBarState(StatusBarState.SHADE_LOCKED);
Jorim Jaggi98f85302014-08-07 17:45:04 +02003480 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003481 if (row != null) {
3482 row.setUserLocked(false);
3483 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003484 }
3485 }
3486
Adrian Roos5a46cd32014-04-03 16:51:58 +02003487 /**
Jorim Jaggi6539a832014-06-03 23:33:09 +02003488 * Goes back to the keyguard after hanging around in {@link StatusBarState#SHADE_LOCKED}.
3489 */
3490 public void goToKeyguard() {
3491 if (mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekd9acca52014-09-01 22:33:25 +02003492 mStackScroller.onGoToKeyguard();
Jorim Jaggi6539a832014-06-03 23:33:09 +02003493 setBarState(StatusBarState.KEYGUARD);
Jorim Jaggi98f85302014-08-07 17:45:04 +02003494 updateKeyguardState(false /* goingToFullShade */, true /* fromShadeLocked*/);
Jorim Jaggi6539a832014-06-03 23:33:09 +02003495 }
3496 }
3497
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003498 public long getKeyguardFadingAwayDelay() {
3499 return mKeyguardFadingAwayDelay;
3500 }
3501
3502 public long getKeyguardFadingAwayDuration() {
3503 return mKeyguardFadingAwayDuration;
3504 }
3505
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003506 @Override
3507 public void setBouncerShowing(boolean bouncerShowing) {
3508 super.setBouncerShowing(bouncerShowing);
Jorim Jaggi2580a9762014-06-25 03:08:25 +02003509 disable(mDisabledUnmodified, true /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003510 }
3511
Jorim Jaggi75c95042014-05-16 19:09:59 +02003512 public void onScreenTurnedOff() {
Jorim Jaggid41083a2014-09-12 02:54:40 +02003513 mScreenOnFromKeyguard = false;
Selim Cinek29ed3c92014-09-23 20:44:35 +02003514 mScreenOnComingFromTouch = false;
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01003515 mScreenOnTouchLocation = null;
Jorim Jaggi75c95042014-05-16 19:09:59 +02003516 mStackScroller.setAnimationsEnabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01003517 updateVisibleToUser();
Jorim Jaggi75c95042014-05-16 19:09:59 +02003518 }
3519
3520 public void onScreenTurnedOn() {
Jorim Jaggid41083a2014-09-12 02:54:40 +02003521 mScreenOnFromKeyguard = true;
Jorim Jaggi75c95042014-05-16 19:09:59 +02003522 mStackScroller.setAnimationsEnabled(true);
Jorim Jaggid09def7512014-09-02 18:36:45 +02003523 mNotificationPanel.onScreenTurnedOn();
Jorim Jaggid41083a2014-09-12 02:54:40 +02003524 mNotificationPanel.setTouchDisabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01003525 updateVisibleToUser();
Jorim Jaggi75c95042014-05-16 19:09:59 +02003526 }
John Spurlockd08f91f2014-05-23 11:00:34 -04003527
Jason Monk815e0572014-08-12 17:26:36 -04003528 /**
3529 * This handles long-press of both back and recents. They are
3530 * handled together to capture them both being long-pressed
3531 * at the same time to exit screen pinning (lock task).
3532 *
3533 * When accessibility mode is on, only a long-press from recents
3534 * is required to exit.
3535 *
3536 * In all other circumstances we try to pass through long-press events
3537 * for Back, so that apps can still use it. Which can be from two things.
3538 * 1) Not currently in screen pinning (lock task).
3539 * 2) Back is long-pressed without recents.
3540 */
3541 private void handleLongPressBackRecents(View v) {
Jason Monk62515be2014-05-21 16:06:19 -04003542 try {
Jason Monk815e0572014-08-12 17:26:36 -04003543 boolean sendBackLongPress = false;
Jason Monk62515be2014-05-21 16:06:19 -04003544 IActivityManager activityManager = ActivityManagerNative.getDefault();
Jason Monk815e0572014-08-12 17:26:36 -04003545 boolean isAccessiblityEnabled = mAccessibilityManager.isEnabled();
3546 if (activityManager.isInLockTaskMode() && !isAccessiblityEnabled) {
3547 long time = System.currentTimeMillis();
3548 // If we recently long-pressed the other button then they were
3549 // long-pressed 'together'
3550 if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERENCE) {
3551 activityManager.stopLockTaskModeOnCurrent();
Jason Monk17488b92014-11-06 11:26:14 -05003552 // When exiting refresh disabled flags.
3553 mNavigationBarView.setDisabledFlags(mDisabled, true);
Jason Monk815e0572014-08-12 17:26:36 -04003554 } else if ((v.getId() == R.id.back)
3555 && !mNavigationBarView.getRecentsButton().isPressed()) {
3556 // If we aren't pressing recents right now then they presses
3557 // won't be together, so send the standard long-press action.
3558 sendBackLongPress = true;
3559 }
3560 mLastLockToAppLongPress = time;
3561 } else {
3562 // If this is back still need to handle sending the long-press event.
3563 if (v.getId() == R.id.back) {
3564 sendBackLongPress = true;
3565 } else if (isAccessiblityEnabled && activityManager.isInLockTaskMode()) {
3566 // When in accessibility mode a long press that is recents (not back)
3567 // should stop lock task.
3568 activityManager.stopLockTaskModeOnCurrent();
Jason Monk17488b92014-11-06 11:26:14 -05003569 // When exiting refresh disabled flags.
3570 mNavigationBarView.setDisabledFlags(mDisabled, true);
Jason Monk815e0572014-08-12 17:26:36 -04003571 }
3572 }
3573 if (sendBackLongPress) {
3574 KeyButtonView keyButtonView = (KeyButtonView) v;
3575 keyButtonView.sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
3576 keyButtonView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
Jason Monk62515be2014-05-21 16:06:19 -04003577 }
3578 } catch (RemoteException e) {
Jason Monk815e0572014-08-12 17:26:36 -04003579 Log.d(TAG, "Unable to reach activity manager", e);
Jason Monk62515be2014-05-21 16:06:19 -04003580 }
3581 }
3582
Winson Chungd42a6cf2014-06-03 16:24:04 -07003583 // Recents
3584
3585 @Override
3586 protected void showRecents(boolean triggeredFromAltTab) {
3587 // Set the recents visibility flag
3588 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
3589 notifyUiVisibilityChanged(mSystemUiVisibility);
3590 super.showRecents(triggeredFromAltTab);
3591 }
3592
3593 @Override
Winson Chungcdcd4872014-08-05 18:00:13 -07003594 protected void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
Winson Chungd42a6cf2014-06-03 16:24:04 -07003595 // Unset the recents visibility flag
3596 mSystemUiVisibility &= ~View.RECENT_APPS_VISIBLE;
3597 notifyUiVisibilityChanged(mSystemUiVisibility);
Winson Chungcdcd4872014-08-05 18:00:13 -07003598 super.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
Winson Chungd42a6cf2014-06-03 16:24:04 -07003599 }
3600
3601 @Override
3602 protected void toggleRecents() {
3603 // Toggle the recents visibility flag
3604 mSystemUiVisibility ^= View.RECENT_APPS_VISIBLE;
3605 notifyUiVisibilityChanged(mSystemUiVisibility);
3606 super.toggleRecents();
3607 }
Winson Chung9214eff2014-06-12 13:59:25 -07003608
3609 @Override
3610 public void onVisibilityChanged(boolean visible) {
3611 // Update the recents visibility flag
3612 if (visible) {
3613 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
3614 } else {
3615 mSystemUiVisibility &= ~View.RECENT_APPS_VISIBLE;
3616 }
3617 notifyUiVisibilityChanged(mSystemUiVisibility);
3618 }
John Spurlockbf370992014-06-17 13:58:31 -04003619
Jason Monk5565cb42014-09-12 10:59:21 -04003620 @Override
3621 public void showScreenPinningRequest() {
Jason Monk18f99d92014-09-11 13:36:42 -04003622 if (mKeyguardMonitor.isShowing()) {
3623 // Don't allow apps to trigger this from keyguard.
3624 return;
3625 }
3626 // Show screen pinning request, since this comes from an app, show 'no thanks', button.
3627 showScreenPinningRequest(true);
3628 }
3629
3630 public void showScreenPinningRequest(boolean allowCancel) {
3631 mScreenPinningRequest.showPrompt(allowCancel);
Jason Monk5565cb42014-09-12 10:59:21 -04003632 }
3633
Christoph Studerc8db24b2014-07-25 17:50:30 +02003634 public boolean hasActiveNotifications() {
3635 return !mNotificationData.getActiveNotifications().isEmpty();
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02003636 }
3637
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01003638 public void wakeUpIfDozing(long time, MotionEvent event) {
Jorim Jaggi048af1f2014-11-11 22:51:10 +01003639 if (mDozing && mDozeScrimController.isPulsing()) {
John Spurlock8b12f222014-09-09 11:54:11 -04003640 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
3641 pm.wakeUp(time);
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01003642 mScreenOnComingFromTouch = true;
3643 mScreenOnTouchLocation = new PointF(event.getX(), event.getY());
3644 mNotificationPanel.setTouchDisabled(false);
John Spurlock8b12f222014-09-09 11:54:11 -04003645 }
3646 }
3647
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01003648 @Override
3649 public void appTransitionPending() {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003650
3651 // Use own timings when Keyguard is going away, see keyguardGoingAway and
3652 // setKeyguardFadingAway
3653 if (!mKeyguardFadingAway) {
3654 mIconController.appTransitionPending();
3655 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01003656 }
3657
3658 @Override
3659 public void appTransitionCancelled() {
3660 mIconController.appTransitionCancelled();
3661 }
3662
3663 @Override
3664 public void appTransitionStarting(long startTime, long duration) {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003665
3666 // Use own timings when Keyguard is going away, see keyguardGoingAway and
3667 // setKeyguardFadingAway
3668 if (!mKeyguardFadingAway) {
3669 mIconController.appTransitionStarting(startTime, duration);
3670 }
Kenny Guy3094d4a2015-04-01 19:14:10 +01003671 if (mIconPolicy != null) {
3672 mIconPolicy.appTransitionStarting(startTime, duration);
3673 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01003674 }
3675
John Spurlockbf370992014-06-17 13:58:31 -04003676 private final class ShadeUpdates {
3677 private final ArraySet<String> mVisibleNotifications = new ArraySet<String>();
3678 private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>();
3679
3680 public void check() {
3681 mNewVisibleNotifications.clear();
Christoph Studerc8db24b2014-07-25 17:50:30 +02003682 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
3683 for (int i = 0; i < activeNotifications.size(); i++) {
3684 final Entry entry = activeNotifications.get(i);
John Spurlockbf370992014-06-17 13:58:31 -04003685 final boolean visible = entry.row != null
3686 && entry.row.getVisibility() == View.VISIBLE;
3687 if (visible) {
3688 mNewVisibleNotifications.add(entry.key + entry.notification.getPostTime());
3689 }
3690 }
3691 final boolean updates = !mVisibleNotifications.containsAll(mNewVisibleNotifications);
3692 mVisibleNotifications.clear();
Dianne Hackborn497175b2014-07-01 12:56:08 -07003693 mVisibleNotifications.addAll(mNewVisibleNotifications);
John Spurlockbf370992014-06-17 13:58:31 -04003694
3695 // We have new notifications
3696 if (updates && mDozeServiceHost != null) {
3697 mDozeServiceHost.fireNewNotifications();
3698 }
3699 }
3700 }
3701
Jeff Brown4d69e222014-09-18 15:27:50 -07003702 private final class DozeServiceHost implements DozeHost {
John Spurlockbf370992014-06-17 13:58:31 -04003703 // Amount of time to allow to update the time shown on the screen before releasing
3704 // the wakelock. This timeout is design to compensate for the fact that we don't
3705 // currently have a way to know when time display contents have actually been
3706 // refreshed once we've finished rendering a new frame.
3707 private static final long PROCESSING_TIME = 500;
3708
3709 private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
3710 private final H mHandler = new H();
3711
Christoph Studer1f32c652014-11-26 15:32:20 +01003712 // Keeps the last reported state by fireNotificationLight.
3713 private boolean mNotificationLightOn;
3714
John Spurlockc6eed842014-08-25 12:19:41 -04003715 @Override
3716 public String toString() {
Jeff Brown4d69e222014-09-18 15:27:50 -07003717 return "PSB.DozeServiceHost[mCallbacks=" + mCallbacks.size() + "]";
John Spurlock8b12f222014-09-09 11:54:11 -04003718 }
3719
John Spurlockd96179e2014-08-21 16:43:45 -04003720 public void firePowerSaveChanged(boolean active) {
3721 for (Callback callback : mCallbacks) {
3722 callback.onPowerSaveChanged(active);
3723 }
3724 }
3725
John Spurlockcad57682014-07-26 17:09:56 -04003726 public void fireBuzzBeepBlinked() {
3727 for (Callback callback : mCallbacks) {
3728 callback.onBuzzBeepBlinked();
3729 }
3730 }
3731
John Spurlockcb566aa2014-08-03 22:58:28 -04003732 public void fireNotificationLight(boolean on) {
Christoph Studer1f32c652014-11-26 15:32:20 +01003733 mNotificationLightOn = on;
John Spurlockcb566aa2014-08-03 22:58:28 -04003734 for (Callback callback : mCallbacks) {
3735 callback.onNotificationLight(on);
3736 }
3737 }
3738
John Spurlockbf370992014-06-17 13:58:31 -04003739 public void fireNewNotifications() {
3740 for (Callback callback : mCallbacks) {
3741 callback.onNewNotifications();
3742 }
3743 }
3744
3745 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07003746 public void addCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04003747 mCallbacks.add(callback);
3748 }
3749
3750 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07003751 public void removeCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04003752 mCallbacks.remove(callback);
3753 }
3754
3755 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07003756 public void startDozing(@NonNull Runnable ready) {
3757 mHandler.obtainMessage(H.MSG_START_DOZING, ready).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04003758 }
3759
3760 @Override
John Spurlockeab28e62014-11-29 11:33:49 -05003761 public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
3762 mHandler.obtainMessage(H.MSG_PULSE_WHILE_DOZING, reason, 0, callback).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04003763 }
3764
3765 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07003766 public void stopDozing() {
3767 mHandler.obtainMessage(H.MSG_STOP_DOZING).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04003768 }
3769
John Spurlockd96179e2014-08-21 16:43:45 -04003770 @Override
3771 public boolean isPowerSaveActive() {
3772 return mBatteryController != null && mBatteryController.isPowerSave();
3773 }
3774
Christoph Studer1f32c652014-11-26 15:32:20 +01003775 @Override
3776 public boolean isNotificationLightOn() {
3777 return mNotificationLightOn;
3778 }
3779
Jeff Brown4d69e222014-09-18 15:27:50 -07003780 private void handleStartDozing(@NonNull Runnable ready) {
John Spurlockbf370992014-06-17 13:58:31 -04003781 if (!mDozing) {
3782 mDozing = true;
John Spurlock813552c2014-09-19 08:30:21 -04003783 DozeLog.traceDozing(mContext, mDozing);
John Spurlockbf370992014-06-17 13:58:31 -04003784 updateDozingState();
3785 }
Jeff Brown4d69e222014-09-18 15:27:50 -07003786 ready.run();
John Spurlockbf370992014-06-17 13:58:31 -04003787 }
3788
John Spurlockeab28e62014-11-29 11:33:49 -05003789 private void handlePulseWhileDozing(@NonNull PulseCallback callback, int reason) {
3790 mDozeScrimController.pulse(callback, reason);
John Spurlockbf370992014-06-17 13:58:31 -04003791 }
3792
Jeff Brown4d69e222014-09-18 15:27:50 -07003793 private void handleStopDozing() {
John Spurlockbf370992014-06-17 13:58:31 -04003794 if (mDozing) {
3795 mDozing = false;
John Spurlock813552c2014-09-19 08:30:21 -04003796 DozeLog.traceDozing(mContext, mDozing);
John Spurlockbf370992014-06-17 13:58:31 -04003797 updateDozingState();
3798 }
3799 }
3800
3801 private final class H extends Handler {
Jeff Brown4d69e222014-09-18 15:27:50 -07003802 private static final int MSG_START_DOZING = 1;
3803 private static final int MSG_PULSE_WHILE_DOZING = 2;
3804 private static final int MSG_STOP_DOZING = 3;
John Spurlockbf370992014-06-17 13:58:31 -04003805
3806 @Override
3807 public void handleMessage(Message msg) {
Jeff Brown4d69e222014-09-18 15:27:50 -07003808 switch (msg.what) {
3809 case MSG_START_DOZING:
3810 handleStartDozing((Runnable) msg.obj);
3811 break;
3812 case MSG_PULSE_WHILE_DOZING:
John Spurlockeab28e62014-11-29 11:33:49 -05003813 handlePulseWhileDozing((PulseCallback) msg.obj, msg.arg1);
Jeff Brown4d69e222014-09-18 15:27:50 -07003814 break;
3815 case MSG_STOP_DOZING:
3816 handleStopDozing();
3817 break;
John Spurlockbf370992014-06-17 13:58:31 -04003818 }
3819 }
3820 }
3821 }
Romain Guy648342f2012-05-25 10:44:45 -07003822}