blob: bd4210c1b034b1e1662dbc2ca3cef2b626af4535 [file] [log] [blame]
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001/*
Jeff Brown37df39a92015-02-25 15:42:31 -08002 * Copyright (C) 2006 The Android Open Source Project
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003 *
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
Jorim Jaggib10e33f2015-02-04 21:57:40 +010017package com.android.server.policy;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080018
Wale Ogunwale5cd907d2017-01-26 14:14:08 -080019import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
20import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
Wale Ogunwale5cd907d2017-01-26 14:14:08 -080021import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
22import static android.app.AppOpsManager.OP_TOAST_WINDOW;
Wale Ogunwale68278562017-09-23 17:13:55 -070023import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
24import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
Wale Ogunwale44f036f2017-09-29 05:09:09 -070025import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
26import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale68278562017-09-23 17:13:55 -070027import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale44f036f2017-09-29 05:09:09 -070028import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale68278562017-09-23 17:13:55 -070029import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Robert Carr7ad24ba2017-06-20 17:26:06 -070030import static android.content.Context.CONTEXT_RESTRICTED;
Andrii Kulianfb1bf692017-01-17 11:17:34 -080031import static android.content.Context.DISPLAY_SERVICE;
32import static android.content.Context.WINDOW_SERVICE;
Dmitri Plotnikov82e6dfc2017-02-24 18:10:54 -080033import static android.content.pm.PackageManager.FEATURE_LEANBACK;
Jorim Jaggif12ec0f2017-08-23 16:14:10 +020034import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
Jaewan Kim49117872016-01-19 17:24:08 +090035import static android.content.pm.PackageManager.FEATURE_WATCH;
Wale Ogunwale5cd907d2017-01-26 14:14:08 -080036import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Wale Ogunwaledfc18622016-04-16 15:08:48 -070037import static android.content.res.Configuration.EMPTY;
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -080038import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
39import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
Wale Ogunwale5cd907d2017-01-26 14:14:08 -080040import static android.os.Build.VERSION_CODES.M;
41import static android.os.Build.VERSION_CODES.O;
Mike Digman55272862018-02-20 14:35:17 -080042import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
Jorim Jaggif12ec0f2017-08-23 16:14:10 +020043import static android.view.Display.DEFAULT_DISPLAY;
44import static android.view.Display.STATE_OFF;
Jorim Jaggi5060bd82016-02-19 17:12:19 -080045import static android.view.WindowManager.DOCKED_LEFT;
46import static android.view.WindowManager.DOCKED_RIGHT;
Jorim Jaggi73294b62016-10-26 18:02:36 -070047import static android.view.WindowManager.DOCKED_TOP;
Winson41275482016-10-10 15:17:45 -070048import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
Jorim Jaggi73294b62016-10-26 18:02:36 -070049import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
50import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
51import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW;
52import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
53import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
54import static android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;
55import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
56import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR;
57import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
58import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN;
59import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
60import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
61import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
62import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwale828ff7e2017-11-14 01:01:29 +000063import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
64import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
Jorim Jaggi73294b62016-10-26 18:02:36 -070065import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
66import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
67import static android.view.WindowManager.LayoutParams.LAST_SYSTEM_WINDOW;
Adrian Roosfa02da62018-01-15 16:01:18 +010068import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
69import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
Jorim Jaggi73294b62016-10-26 18:02:36 -070070import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
Jorim Jaggif12ec0f2017-08-23 16:14:10 +020071import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_ACQUIRES_SLEEP_TOKEN;
Jorim Jaggi73294b62016-10-26 18:02:36 -070072import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
73import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
Wale Ogunwale828ff7e2017-11-14 01:01:29 +000074import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR;
Adrian Roos4bef62e2018-03-21 19:52:09 +010075import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
Wale Ogunwalec0b0f932017-11-01 12:51:43 -070076import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
Jorim Jaggi73294b62016-10-26 18:02:36 -070077import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
78import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
79import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
80import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
81import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
82import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
83import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
84import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
85import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
86import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
87import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
Wale Ogunwale5cd907d2017-01-26 14:14:08 -080088import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
Jorim Jaggif12ec0f2017-08-23 16:14:10 +020089import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Adrian Roosc8045bf2018-03-29 19:41:30 +020090import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Jorim Jaggi73294b62016-10-26 18:02:36 -070091import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
92import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY;
93import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
Jorim Jaggi73294b62016-10-26 18:02:36 -070094import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
95import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
96import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
Jorim Jaggi73294b62016-10-26 18:02:36 -070097import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
98import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
99import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
100import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
101import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
102import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
Wale Ogunwale5b6714c2016-11-01 20:54:46 -0700103import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
Jorim Jaggi73294b62016-10-26 18:02:36 -0700104import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
105import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
106import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
107import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
108import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR;
109import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
110import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
111import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
112import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
113import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
114import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
115import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
116import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
117import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
118import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
119import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING;
120import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
121import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800122import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
Muyuan Li6ca619f2016-03-08 13:30:42 -0800123import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
124import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION;
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800125import static android.view.WindowManagerGlobal.ADD_OKAY;
126import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED;
Adrian Roose99bc052017-11-20 17:55:31 +0100127
128import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
129import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT;
130import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED;
131import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
132import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
133import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
Yi Jin6c6e9ca2018-03-20 16:53:35 -0700134import static com.android.server.wm.WindowManagerPolicyProto.FOCUSED_APP_TOKEN;
135import static com.android.server.wm.WindowManagerPolicyProto.FOCUSED_WINDOW;
136import static com.android.server.wm.WindowManagerPolicyProto.FORCE_STATUS_BAR;
137import static com.android.server.wm.WindowManagerPolicyProto.FORCE_STATUS_BAR_FROM_KEYGUARD;
138import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_DELEGATE;
139import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_DRAW_COMPLETE;
140import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_OCCLUDED;
141import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_OCCLUDED_CHANGED;
142import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_OCCLUDED_PENDING;
143import static com.android.server.wm.WindowManagerPolicyProto.LAST_SYSTEM_UI_FLAGS;
144import static com.android.server.wm.WindowManagerPolicyProto.NAVIGATION_BAR;
145import static com.android.server.wm.WindowManagerPolicyProto.ORIENTATION;
146import static com.android.server.wm.WindowManagerPolicyProto.ORIENTATION_LISTENER;
147import static com.android.server.wm.WindowManagerPolicyProto.ROTATION;
148import static com.android.server.wm.WindowManagerPolicyProto.ROTATION_MODE;
149import static com.android.server.wm.WindowManagerPolicyProto.SCREEN_ON_FULLY;
150import static com.android.server.wm.WindowManagerPolicyProto.STATUS_BAR;
151import static com.android.server.wm.WindowManagerPolicyProto.TOP_FULLSCREEN_OPAQUE_OR_DIMMING_WINDOW;
152import static com.android.server.wm.WindowManagerPolicyProto.TOP_FULLSCREEN_OPAQUE_WINDOW;
153import static com.android.server.wm.WindowManagerPolicyProto.WINDOW_MANAGER_DRAW_COMPLETE;
Wale Ogunwale6e94a9e2015-10-07 15:35:49 -0700154
Jorim Jaggife762342016-10-13 14:33:27 +0200155import android.annotation.Nullable;
Dianne Hackborna4972e92012-03-14 10:38:05 -0700156import android.app.ActivityManager;
Jeff Brown061ea992015-04-17 19:55:47 -0700157import android.app.ActivityManagerInternal;
158import android.app.ActivityManagerInternal.SleepToken;
Jason Monkf506bf32017-08-23 10:56:34 -0400159import android.app.ActivityThread;
Dianne Hackbornc2293022013-02-06 23:14:49 -0800160import android.app.AppOpsManager;
Daniel Sandler6396c722013-04-16 20:19:09 -0400161import android.app.IUiModeManager;
Dianne Hackborn661cd522011-08-22 00:26:20 -0700162import android.app.ProgressDialog;
Jeff Brownde7a8ea2012-06-13 18:28:57 -0700163import android.app.SearchManager;
John Spurlock97642182013-07-29 17:58:39 -0400164import android.app.StatusBarManager;
Dianne Hackborn78968392010-03-04 20:47:56 -0800165import android.app.UiModeManager;
Dianne Hackborn39c2d712009-09-22 11:41:31 -0700166import android.content.ActivityNotFoundException;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800167import android.content.BroadcastReceiver;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800168import android.content.ContentResolver;
169import android.content.Context;
170import android.content.Intent;
Mike Lockwood1753f7f2009-08-24 14:49:07 -0700171import android.content.IntentFilter;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800172import android.content.pm.ActivityInfo;
Svet Ganov03f2afc2016-03-04 16:13:03 -0800173import android.content.pm.ApplicationInfo;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800174import android.content.pm.PackageManager;
Daniel Sandler6396c722013-04-16 20:19:09 -0400175import android.content.pm.ResolveInfo;
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700176import android.content.res.CompatibilityInfo;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800177import android.content.res.Configuration;
178import android.content.res.Resources;
Wale Ogunwaledfc18622016-04-16 15:08:48 -0700179import android.content.res.TypedArray;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800180import android.database.ContentObserver;
Dianne Hackbornc777e072010-02-12 13:07:59 -0800181import android.graphics.PixelFormat;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800182import android.graphics.Rect;
Jorim Jaggi7d0d1022017-02-23 15:35:51 +0100183import android.graphics.drawable.Drawable;
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800184import android.hardware.display.DisplayManager;
Jinsuk Kime601b712015-07-07 08:01:02 +0900185import android.hardware.hdmi.HdmiControlManager;
186import android.hardware.hdmi.HdmiPlaybackClient;
187import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
Vladislav Kaznacheev19dab2d2017-02-07 10:12:51 -0800188import android.hardware.input.InputManager;
Andrii Kulian112d0562016-03-08 10:44:22 -0800189import android.hardware.input.InputManagerInternal;
Ruchi Kandoi0d434042016-10-03 09:12:02 -0700190import android.hardware.power.V1_0.PowerHint;
John Spurlock7b414672014-07-18 13:02:39 -0400191import android.media.AudioAttributes;
Michael Jurka7a348952012-02-27 13:07:58 -0800192import android.media.AudioManager;
Mike Digman55272862018-02-20 14:35:17 -0800193import android.media.AudioManagerInternal;
John Spurlock61560172015-02-06 19:46:04 -0500194import android.media.AudioSystem;
Michael Jurka7a348952012-02-27 13:07:58 -0800195import android.media.IAudioService;
RoboErik8a2cfc32014-05-16 11:19:38 -0700196import android.media.session.MediaSessionLegacyHelper;
Billy Laucbe540f2015-06-25 01:51:44 +0100197import android.os.Binder;
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700198import android.os.Bundle;
Jeff Brown9a538ee2012-08-20 14:56:57 -0700199import android.os.FactoryTest;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800200import android.os.Handler;
201import android.os.IBinder;
Dianne Hackbornb6683c42015-06-18 17:40:33 -0700202import android.os.IDeviceIdleController;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800203import android.os.Looper;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -0700204import android.os.Message;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800205import android.os.PowerManager;
Nick Armstrong-Crews56ecfcc2015-09-07 21:46:50 -0700206import android.os.PowerManagerInternal;
Billy Laucbe540f2015-06-25 01:51:44 +0100207import android.os.Process;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800208import android.os.RemoteException;
209import android.os.ServiceManager;
Jeff Sharkey89182982017-11-01 19:02:56 -0600210import android.os.StrictMode;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800211import android.os.SystemClock;
212import android.os.SystemProperties;
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -0800213import android.os.UEventObserver;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700214import android.os.UserHandle;
Michael Wright71216972017-01-31 18:33:54 +0000215import android.os.VibrationEffect;
Jorim Jaggif12ec0f2017-08-23 16:14:10 +0200216import android.os.Vibrator;
Michael Wright3818c922014-09-02 13:59:07 -0700217import android.provider.MediaStore;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800218import android.provider.Settings;
Jose Lima9546b202014-07-02 17:21:51 -0700219import android.service.dreams.DreamManagerInternal;
John Spurlockc8b46ca2013-04-08 12:59:26 -0400220import android.service.dreams.DreamService;
221import android.service.dreams.IDreamManager;
Santos Cordonc09d89c2017-04-13 16:12:02 -0700222import android.service.vr.IPersistentVrStateCallbacks;
Michael Wrightdc63f7b2014-08-21 19:05:21 -0700223import android.speech.RecognizerIntent;
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700224import android.telecom.TelecomManager;
Wale Ogunwalec0b0f932017-11-01 12:51:43 -0700225import android.util.ArraySet;
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700226import android.util.DisplayMetrics;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800227import android.util.EventLog;
228import android.util.Log;
Jorim Jaggi73294b62016-10-26 18:02:36 -0700229import android.util.LongSparseArray;
Jorim Jaggif1cdf952016-04-05 21:41:06 -0700230import android.util.MutableBoolean;
Michael Wright19859762017-09-18 20:57:58 +0100231import android.util.PrintWriterPrinter;
Jeff Browna41ca772010-08-11 14:46:32 -0700232import android.util.Slog;
Jeff Brown6651a632011-11-28 12:59:11 -0800233import android.util.SparseArray;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700234import android.util.proto.ProtoOutputStream;
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700235import android.view.Display;
Adrian Roos5c6b6222017-11-07 17:36:10 +0100236import android.view.DisplayCutout;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800237import android.view.Gravity;
238import android.view.HapticFeedbackConstants;
Dianne Hackborne0f085d2011-11-30 18:41:15 -0800239import android.view.IApplicationToken;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800240import android.view.IWindowManager;
Jeff Browna41ca772010-08-11 14:46:32 -0700241import android.view.InputChannel;
Jeff Brown4d396052010-10-29 21:50:21 -0700242import android.view.InputDevice;
Jeff Brown4952dfd2011-11-30 19:23:22 -0800243import android.view.InputEvent;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800244import android.view.InputEventReceiver;
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800245import android.view.KeyCharacterMap;
Craig Mautnerae446592012-12-06 19:05:05 -0800246import android.view.KeyCharacterMap.FallbackAction;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800247import android.view.KeyEvent;
248import android.view.MotionEvent;
Vladislav Kaznacheev19dab2d2017-02-07 10:12:51 -0800249import android.view.PointerIcon;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800250import android.view.Surface;
251import android.view.View;
252import android.view.ViewConfiguration;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800253import android.view.WindowManager;
Jorim Jaggife762342016-10-13 14:33:27 +0200254import android.view.WindowManager.LayoutParams;
Craig Mautnerae446592012-12-06 19:05:05 -0800255import android.view.WindowManagerGlobal;
Craig Mautnerae446592012-12-06 19:05:05 -0800256import android.view.accessibility.AccessibilityEvent;
Svetoslav8e3feb12014-02-24 13:46:47 -0800257import android.view.accessibility.AccessibilityManager;
Craig Mautnerae446592012-12-06 19:05:05 -0800258import android.view.animation.Animation;
Jorim Jaggi76a16232014-08-08 17:00:47 +0200259import android.view.animation.AnimationSet;
Craig Mautnerae446592012-12-06 19:05:05 -0800260import android.view.animation.AnimationUtils;
Felipe Leme5f978802017-06-08 13:01:13 -0700261import android.view.autofill.AutofillManagerInternal;
Yohei Yukawad6475a62017-04-17 10:35:27 -0700262import android.view.inputmethod.InputMethodManagerInternal;
Yohei Yukawaabbe1ac2017-04-18 09:43:05 -0700263
Craig Mautnerae446592012-12-06 19:05:05 -0800264import com.android.internal.R;
Phil Weaverb9f06122017-11-30 10:48:17 -0800265import com.android.internal.accessibility.AccessibilityShortcutController;
Jorim Jaggif12ec0f2017-08-23 16:14:10 +0200266import com.android.internal.annotations.GuardedBy;
Adrian Roose1856fe2017-11-24 19:39:12 +0100267import com.android.internal.annotations.VisibleForTesting;
Jason Monk8f7f3182015-11-18 16:35:14 -0500268import com.android.internal.logging.MetricsLogger;
Jorim Jaggi241ae102016-11-02 21:57:33 -0700269import com.android.internal.policy.IKeyguardDismissCallback;
Muyuan Li94ce94e2016-02-24 16:20:54 -0800270import com.android.internal.policy.IShortcutService;
Winson Chung2a35e6d2018-01-13 14:27:50 -0800271import com.android.internal.policy.KeyguardDismissCallback;
Jorim Jaggi73294b62016-10-26 18:02:36 -0700272import com.android.internal.policy.PhoneWindow;
Craig Mautnerae446592012-12-06 19:05:05 -0800273import com.android.internal.statusbar.IStatusBarService;
Phil Weaverb9f06122017-11-30 10:48:17 -0800274import com.android.internal.util.ArrayUtils;
Alison Cichowlasa2cd19e2017-12-06 10:51:21 -0500275import com.android.internal.util.ScreenshotHelper;
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700276import com.android.internal.util.ScreenShapeHelper;
Craig Mautnerae446592012-12-06 19:05:05 -0800277import com.android.internal.widget.PointerLocationView;
Adrian Roos5941c982015-09-03 15:59:49 -0700278import com.android.server.GestureLauncherService;
Craig Mautner8a0da012014-05-31 15:13:37 -0700279import com.android.server.LocalServices;
Keun-young Park4136d2d2017-05-08 14:51:59 -0700280import com.android.server.SystemServiceManager;
Jorim Jaggib10e33f2015-02-04 21:57:40 +0100281import com.android.server.policy.keyguard.KeyguardServiceDelegate;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700282import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
Jorim Jaggie69c9312016-10-31 18:24:38 -0700283import com.android.server.policy.keyguard.KeyguardStateMonitor.StateCallback;
Jorim Jaggi86905582016-02-09 21:36:09 -0800284import com.android.server.statusbar.StatusBarManagerInternal;
Ruben Brunkfecb6152016-10-28 20:18:57 -0700285import com.android.server.vr.VrManagerInternal;
Jorim Jaggif12ec0f2017-08-23 16:14:10 +0200286import com.android.server.wm.AppTransition;
Adrian Roose99bc052017-11-20 17:55:31 +0100287import com.android.server.wm.DisplayFrames;
288import com.android.server.wm.WindowManagerInternal;
289import com.android.server.wm.WindowManagerInternal.AppTransitionListener;
Craig Mautnerae446592012-12-06 19:05:05 -0800290
291import java.io.File;
292import java.io.FileReader;
293import java.io.IOException;
294import java.io.PrintWriter;
Craig Mautner276a6eb2014-11-04 15:32:57 -0800295import java.util.List;
Craig Mautnerae446592012-12-06 19:05:05 -0800296
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800297/**
The Android Open Source Project0727d222009-03-11 12:11:58 -0700298 * WindowManagerPolicy implementation for the Android phone UI. This
299 * introduces a new method suffix, Lp, for an internal lock of the
300 * PhoneWindowManager. This is used to protect some internal state, and
John Spurlock04db1762013-05-13 12:46:41 -0400301 * can be acquired with either the Lw and Li lock held, so has the restrictions
The Android Open Source Project0727d222009-03-11 12:11:58 -0700302 * of both of those when held.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800303 */
304public class PhoneWindowManager implements WindowManagerPolicy {
305 static final String TAG = "WindowManager";
306 static final boolean DEBUG = false;
Joe Onorato43a17652011-04-06 19:22:23 -0700307 static final boolean localLOGV = false;
Jeff Brown40013652012-05-16 21:22:36 -0700308 static final boolean DEBUG_INPUT = false;
Craig Mautnerc0d2d0a2014-10-31 16:25:15 -0700309 static final boolean DEBUG_KEYGUARD = false;
310 static final boolean DEBUG_LAYOUT = false;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800311 static final boolean DEBUG_SPLASH_SCREEN = false;
Craig Mautner8a0da012014-05-31 15:13:37 -0700312 static final boolean DEBUG_WAKEUP = false;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800313 static final boolean SHOW_SPLASH_SCREENS = true;
Joe Onoratod208e702010-10-08 16:22:43 -0400314
Daniel Sandler6396c722013-04-16 20:19:09 -0400315 // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
keunyounga7710492015-09-23 11:33:58 -0700316 // No longer recommended for desk docks;
Daniel Sandler6396c722013-04-16 20:19:09 -0400317 static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
318
Zak Cohendb6ca492017-01-26 14:09:00 -0800319 // Whether to allow devices placed in vr headset viewers to have an alternative Home intent.
320 static final boolean ENABLE_VR_HEADSET_HOME_CAPTURE = true;
321
Justin Paupore01915a12016-09-28 17:41:26 -0700322 static final boolean ALTERNATE_CAR_MODE_NAV_SIZE = false;
323
Jeff Brown6d8fd272014-05-20 21:24:38 -0700324 static final int SHORT_PRESS_POWER_NOTHING = 0;
325 static final int SHORT_PRESS_POWER_GO_TO_SLEEP = 1;
326 static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP = 2;
327 static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME = 3;
Bryce Lee01b0c5f2015-02-05 18:24:04 -0800328 static final int SHORT_PRESS_POWER_GO_HOME = 4;
Yohei Yukawad6475a62017-04-17 10:35:27 -0700329 static final int SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME = 5;
Jeff Brown6d8fd272014-05-20 21:24:38 -0700330
Joe Onoratod208e702010-10-08 16:22:43 -0400331 static final int LONG_PRESS_POWER_NOTHING = 0;
332 static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
333 static final int LONG_PRESS_POWER_SHUT_OFF = 2;
Jeff Brown9a538ee2012-08-20 14:56:57 -0700334 static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3;
Michael Kwan57908f02017-11-14 15:27:53 -0800335 static final int LONG_PRESS_POWER_GO_TO_VOICE_ASSIST = 4;
336
337 static final int VERY_LONG_PRESS_POWER_NOTHING = 0;
338 static final int VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
Michael Jurka3b1fc472011-06-13 10:54:40 -0700339
Jeff Brown13f00f02014-10-31 14:45:50 -0700340 static final int MULTI_PRESS_POWER_NOTHING = 0;
341 static final int MULTI_PRESS_POWER_THEATER_MODE = 1;
342 static final int MULTI_PRESS_POWER_BRIGHTNESS_BOOST = 2;
343
Michael Wright19859762017-09-18 20:57:58 +0100344 static final int LONG_PRESS_BACK_NOTHING = 0;
345 static final int LONG_PRESS_BACK_GO_TO_VOICE_ASSIST = 1;
346
Michael Jurka3b1fc472011-06-13 10:54:40 -0700347 // These need to match the documentation/constant in
348 // core/res/res/values/config.xml
Joe Onorato46b0d682010-11-22 17:37:27 -0800349 static final int LONG_PRESS_HOME_NOTHING = 0;
Sid Soundararajanff662fa2017-03-15 16:24:24 -0700350 static final int LONG_PRESS_HOME_ALL_APPS = 1;
Jeff Browncaca8812013-05-09 13:34:33 -0700351 static final int LONG_PRESS_HOME_ASSIST = 2;
Jaewan Kim76b7d0d2016-02-12 19:01:02 +0900352 static final int LAST_LONG_PRESS_HOME_BEHAVIOR = LONG_PRESS_HOME_ASSIST;
Jeff Browncaca8812013-05-09 13:34:33 -0700353
354 static final int DOUBLE_TAP_HOME_NOTHING = 0;
355 static final int DOUBLE_TAP_HOME_RECENT_SYSTEM_UI = 1;
Joe Onorato46b0d682010-11-22 17:37:27 -0800356
Jaewan Kim49117872016-01-19 17:24:08 +0900357 static final int SHORT_PRESS_WINDOW_NOTHING = 0;
358 static final int SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE = 1;
359
Filip Gruszczynskia483a1d2015-03-17 19:06:58 +0000360 static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP = 0;
361 static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME = 1;
362
Anthony Hugh4b13ab82016-05-17 13:03:00 -0700363 static final int PENDING_KEY_NULL = -1;
364
Yorke Lee9b2ffb32016-03-07 20:42:01 -0800365 // Controls navigation bar opacity depending on which workspace stacks are currently
366 // visible.
367 // Nav bar is always opaque when either the freeform stack or docked stack is visible.
368 static final int NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED = 0;
369 // Nav bar is always translucent when the freeform stack is visible, otherwise always opaque.
370 static final int NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE = 1;
371
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800372 static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
373 static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
374 static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
Joe Onoratof275f0c2009-11-24 16:11:13 -0500375 static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
Jeff Brownde7a8ea2012-06-13 18:28:57 -0700376 static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";
Winson Chunged376a32017-09-07 14:05:42 -0700377 static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800378
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700379 /**
380 * These are the system UI flags that, when changing, can cause the layout
381 * of the screen to change.
382 */
383 static final int SYSTEM_UI_CHANGING_LAYOUT =
John Spurlocke1f366f2013-08-05 12:22:40 -0400384 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
John Spurlock7f4820a2013-10-08 12:54:35 -0400385 | View.SYSTEM_UI_FLAG_FULLSCREEN
386 | View.STATUS_BAR_TRANSLUCENT
Adrian Roosea562512014-05-05 13:33:03 +0200387 | View.NAVIGATION_BAR_TRANSLUCENT
Jorim Jaggi4fa78922015-11-30 17:13:56 -0800388 | View.STATUS_BAR_TRANSPARENT
389 | View.NAVIGATION_BAR_TRANSPARENT;
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700390
John Spurlock7b414672014-07-18 13:02:39 -0400391 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
392 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
393 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
394 .build();
395
Adrian Roosddc8b272015-05-21 16:28:27 -0700396 // The panic gesture may become active only after the keyguard is dismissed and the immersive
397 // app shows again. If that doesn't happen for 30s we drop the gesture.
398 private static final long PANIC_GESTURE_EXPIRATION = 30000;
399
Winson44dbe292016-03-10 14:00:14 -0800400 private static final String SYSUI_PACKAGE = "com.android.systemui";
401 private static final String SYSUI_SCREENSHOT_SERVICE =
402 "com.android.systemui.screenshot.TakeScreenshotService";
403 private static final String SYSUI_SCREENSHOT_ERROR_RECEIVER =
404 "com.android.systemui.screenshot.ScreenshotServiceErrorReceiver";
405
Jim Miller5ecd8112013-01-09 18:50:26 -0800406 /**
407 * Keyguard stuff
408 */
Jeff Brown3ee549c2014-09-22 20:14:39 -0700409 private boolean mKeyguardDrawnOnce;
Jim Miller5ecd8112013-01-09 18:50:26 -0800410
Jeff Brown6651a632011-11-28 12:59:11 -0800411 /* Table of Application Launch keys. Maps from key codes to intent categories.
412 *
413 * These are special keys that are used to launch particular kinds of applications,
414 * such as a web browser. HID defines nearly a hundred of them in the Consumer (0x0C)
415 * usage page. We don't support quite that many yet...
416 */
417 static SparseArray<String> sApplicationLaunchKeyCategories;
418 static {
419 sApplicationLaunchKeyCategories = new SparseArray<String>();
420 sApplicationLaunchKeyCategories.append(
421 KeyEvent.KEYCODE_EXPLORER, Intent.CATEGORY_APP_BROWSER);
422 sApplicationLaunchKeyCategories.append(
423 KeyEvent.KEYCODE_ENVELOPE, Intent.CATEGORY_APP_EMAIL);
424 sApplicationLaunchKeyCategories.append(
425 KeyEvent.KEYCODE_CONTACTS, Intent.CATEGORY_APP_CONTACTS);
426 sApplicationLaunchKeyCategories.append(
427 KeyEvent.KEYCODE_CALENDAR, Intent.CATEGORY_APP_CALENDAR);
428 sApplicationLaunchKeyCategories.append(
429 KeyEvent.KEYCODE_MUSIC, Intent.CATEGORY_APP_MUSIC);
430 sApplicationLaunchKeyCategories.append(
431 KeyEvent.KEYCODE_CALCULATOR, Intent.CATEGORY_APP_CALCULATOR);
432 }
433
Yoshiaki Nakae1bdfc822017-09-15 15:24:34 +0900434 private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
435
Craig Mautnerc3daedd2014-09-13 11:17:23 -0700436 /** Amount of time (in milliseconds) to wait for windows drawn before powering on. */
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700437 static final int WAITING_FOR_DRAWN_TIMEOUT = 1000;
Craig Mautnerc3daedd2014-09-13 11:17:23 -0700438
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700439 /** Amount of time (in milliseconds) a toast window can be shown. */
440 public static final int TOAST_WINDOW_TIMEOUT = 3500; // 3.5 seconds
441
Dianne Hackborndf89e652011-10-06 22:35:11 -0700442 /**
443 * Lock protecting internal state. Must not call out into window
444 * manager with lock held. (This lock will be acquired in places
445 * where the window manager is calling in with its own lock held.)
446 */
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800447 private final Object mLock = new Object();
Dianne Hackborndf89e652011-10-06 22:35:11 -0700448
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800449 Context mContext;
450 IWindowManager mWindowManager;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700451 WindowManagerFuncs mWindowManagerFuncs;
Craig Mautner8a0da012014-05-31 15:13:37 -0700452 WindowManagerInternal mWindowManagerInternal;
Jeff Brown96307042012-07-27 15:51:34 -0700453 PowerManager mPowerManager;
Jeff Brown061ea992015-04-17 19:55:47 -0700454 ActivityManagerInternal mActivityManagerInternal;
Felipe Leme5f978802017-06-08 13:01:13 -0700455 AutofillManagerInternal mAutofillManagerInternal;
Andrii Kulian112d0562016-03-08 10:44:22 -0800456 InputManagerInternal mInputManagerInternal;
Yohei Yukawad6475a62017-04-17 10:35:27 -0700457 InputMethodManagerInternal mInputMethodManagerInternal;
Jose Lima9546b202014-07-02 17:21:51 -0700458 DreamManagerInternal mDreamManagerInternal;
Michael Wrighta4d22d72015-09-16 23:19:26 +0100459 PowerManagerInternal mPowerManagerInternal;
Joe Onorato93056472010-09-10 10:30:46 -0400460 IStatusBarService mStatusBarService;
Jorim Jaggi86905582016-02-09 21:36:09 -0800461 StatusBarManagerInternal mStatusBarManagerInternal;
Mike Digman55272862018-02-20 14:35:17 -0800462 AudioManagerInternal mAudioManagerInternal;
Jeff Browncaca8812013-05-09 13:34:33 -0700463 boolean mPreloadedRecentApps;
Dianne Hackborn42e620c2012-06-24 13:20:51 -0700464 final Object mServiceAquireLock = new Object();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800465 Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
Jeff Brownde7a8ea2012-06-13 18:28:57 -0700466 SearchManager mSearchManager;
Svetoslav8e3feb12014-02-24 13:46:47 -0800467 AccessibilityManager mAccessibilityManager;
Filip Gruszczynskicfb31852015-02-25 21:47:12 +0000468 BurnInProtectionHelper mBurnInProtectionHelper;
Billy Laucbe540f2015-06-25 01:51:44 +0100469 AppOpsManager mAppOpsManager;
Alison Cichowlasa2cd19e2017-12-06 10:51:21 -0500470 private ScreenshotHelper mScreenshotHelper;
Wale Ogunwale6b15ea52016-04-04 07:28:27 -0700471 private boolean mHasFeatureWatch;
Dmitri Plotnikov82e6dfc2017-02-24 18:10:54 -0800472 private boolean mHasFeatureLeanback;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800473
Zak Cohen732aeb02017-01-29 14:19:52 -0800474 // Assigned on main thread, accessed on UI thread
475 volatile VrManagerInternal mVrManagerInternal;
476
Dianne Hackborn181ceb52009-08-27 22:16:40 -0700477 // Vibrator pattern for haptic feedback of a long press.
478 long[] mLongPressVibePattern;
Craig Mautner88400d32012-09-30 12:35:45 -0700479
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700480 // Vibrator pattern for a short vibration when tapping on a day/month/year date of a Calendar.
481 long[] mCalendarDateVibePattern;
482
Dianne Hackbornb1a79802009-09-29 15:18:31 -0700483 // Vibrator pattern for haptic feedback during boot when safe mode is enabled.
484 long[] mSafeModeEnabledVibePattern;
Romain Guy8154cd32010-03-29 14:41:15 -0700485
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800486 /** If true, hitting shift & menu will broadcast Intent.ACTION_BUG_REPORT */
487 boolean mEnableShiftMenuBugReports = false;
Mike Lockwoodd747dc82011-09-13 16:28:22 -0400488
Phil Weaver106fe732016-11-22 18:18:39 -0800489 /** Controller that supports enabling an AccessibilityService by holding down the volume keys */
490 private AccessibilityShortcutController mAccessibilityShortcutController;
491
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800492 boolean mSafeMode;
Wale Ogunwalec0b0f932017-11-01 12:51:43 -0700493 private final ArraySet<WindowState> mScreenDecorWindows = new ArraySet<>();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800494 WindowState mStatusBar = null;
Adrian Roos22af6502018-02-22 16:57:08 +0100495 private final int[] mStatusBarHeightForRotation = new int[4];
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400496 WindowState mNavigationBar = null;
Daniel Sandler36412a72011-08-04 09:35:13 -0400497 boolean mHasNavigationBar = false;
Daniel Sandler4a066c52012-04-20 14:49:13 -0400498 boolean mNavigationBarCanMove = false; // can the navigation bar ever move to the side?
Yohei Yukawad0a66b22018-01-10 13:19:54 -0800499 @NavigationBarPosition
Adrian Roos85d202b2016-06-02 16:27:47 -0700500 int mNavigationBarPosition = NAV_BAR_BOTTOM;
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800501 int[] mNavigationBarHeightForRotationDefault = new int[4];
502 int[] mNavigationBarWidthForRotationDefault = new int[4];
503 int[] mNavigationBarHeightForRotationInCarMode = new int[4];
504 int[] mNavigationBarWidthForRotationInCarMode = new int[4];
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400505
Muyuan Li94ce94e2016-02-24 16:20:54 -0800506 private LongSparseArray<IShortcutService> mShortcutKeyServices = new LongSparseArray<>();
507
keunyounga7710492015-09-23 11:33:58 -0700508 // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
509 // This is for car dock and this is updated from resource.
510 private boolean mEnableCarDockHomeCapture = true;
511
Craig Mautnera631d492014-08-05 15:16:01 -0700512 boolean mBootMessageNeedsHiding;
Jim Miller5ecd8112013-01-09 18:50:26 -0800513 KeyguardServiceDelegate mKeyguardDelegate;
Keun-young Park4136d2d2017-05-08 14:51:59 -0700514 private boolean mKeyguardBound;
Craig Mautner13f6ea72014-06-23 14:57:02 -0700515 final Runnable mWindowManagerDrawCallback = new Runnable() {
Craig Mautner8a0da012014-05-31 15:13:37 -0700516 @Override
Craig Mautner13f6ea72014-06-23 14:57:02 -0700517 public void run() {
Craig Mautner8a0da012014-05-31 15:13:37 -0700518 if (DEBUG_WAKEUP) Slog.i(TAG, "All windows ready for display!");
519 mHandler.sendEmptyMessage(MSG_WINDOW_MANAGER_DRAWN_COMPLETE);
520 }
521 };
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700522 final DrawnListener mKeyguardDrawnCallback = new DrawnListener() {
Craig Mautner8a0da012014-05-31 15:13:37 -0700523 @Override
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700524 public void onDrawn() {
525 if (DEBUG_WAKEUP) Slog.d(TAG, "mKeyguardDelegate.ShowListener.onDrawn.");
Craig Mautner8a0da012014-05-31 15:13:37 -0700526 mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE);
527 }
528 };
529
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800530 GlobalActions mGlobalActions;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800531 Handler mHandler;
satok1bc0a492012-04-25 22:47:12 +0900532 WindowState mLastInputMethodWindow = null;
533 WindowState mLastInputMethodTargetWindow = null;
Jeff Brown4aed78b2011-01-14 17:36:55 -0800534
Jeff Brown13f00f02014-10-31 14:45:50 -0700535 // FIXME This state is shared between the input reader and handler thread.
536 // Technically it's broken and buggy but it has been like this for many years
537 // and we have not yet seen any problems. Someday we'll rewrite this logic
538 // so that only one thread is involved in handling input policy. Unfortunately
539 // it's on a critical path for power management so we can't just post the work to the
540 // handler thread. We'll need to resolve this someday by teaching the input dispatcher
541 // to hold wakelocks during dispatch and eliminating the critical path.
542 volatile boolean mPowerKeyHandled;
Anthony Hugh34f09ca2016-03-04 12:03:37 -0800543 volatile boolean mBackKeyHandled;
Bryce Leed9268e32014-11-17 17:40:59 -0800544 volatile boolean mBeganFromNonInteractive;
Jeff Brown13f00f02014-10-31 14:45:50 -0700545 volatile int mPowerKeyPressCounter;
546 volatile boolean mEndCallKeyHandled;
Jorim Jaggif1cdf952016-04-05 21:41:06 -0700547 volatile boolean mCameraGestureTriggeredDuringGoingToSleep;
548 volatile boolean mGoingToSleep;
Selim Cinekab55ba52017-08-02 16:45:51 -0700549 volatile boolean mRequestedOrGoingToSleep;
Jaewan Kimf0fd2182016-04-20 21:17:58 +0900550 volatile boolean mRecentsVisible;
Matthew Ng64543e62018-02-28 17:35:10 -0800551 volatile boolean mNavBarVirtualKeyHapticFeedbackEnabled;
Winson Chungac52f282017-03-30 14:44:52 -0700552 volatile boolean mPictureInPictureVisible;
Santos Cordonc09d89c2017-04-13 16:12:02 -0700553 // Written by vr manager thread, only read in this class.
554 volatile private boolean mPersistentVrModeEnabled;
Yohei Yukawaabbe1ac2017-04-18 09:43:05 -0700555 volatile private boolean mDismissImeOnBackKeyPressed;
Jeff Brown13f00f02014-10-31 14:45:50 -0700556
Anthony Hugh4b13ab82016-05-17 13:03:00 -0700557 // Used to hold the last user key used to wake the device. This helps us prevent up events
558 // from being passed to the foregrounded app without a corresponding down event
559 volatile int mPendingWakeKey = PENDING_KEY_NULL;
560
Winson Chung1e8d71b2014-05-16 17:05:22 -0700561 int mRecentAppsHeldModifiers;
Jeff Browncf39bdf2012-05-18 14:41:19 -0700562 boolean mLanguageSwitchKeyPressed;
Jeff Brown68b909d2011-12-07 16:36:01 -0800563
Jeff Brown2e7760e2012-04-11 15:14:55 -0700564 int mLidState = LID_ABSENT;
Michael Wright3818c922014-09-02 13:59:07 -0700565 int mCameraLensCoverState = CAMERA_LENS_COVER_ABSENT;
Jeff Browndaa37532012-05-01 15:54:03 -0700566 boolean mHaveBuiltInKeyboard;
Jeff Brown4aed78b2011-01-14 17:36:55 -0800567
Dianne Hackbornc777e072010-02-12 13:07:59 -0800568 boolean mSystemReady;
Dianne Hackbornba24e4d2011-09-01 11:17:06 -0700569 boolean mSystemBooted;
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -0800570 boolean mHdmiPlugged;
Jinsuk Kime601b712015-07-07 08:01:02 +0900571 HdmiControl mHdmiControl;
Jeff Brown4f5fa282014-06-12 19:19:15 -0700572 IUiModeManager mUiModeManager;
Daniel Sandler6396c722013-04-16 20:19:09 -0400573 int mUiMode;
Dianne Hackborn867ab6472010-04-29 13:28:56 -0700574 int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
Mike Lockwood1753f7f2009-08-24 14:49:07 -0700575 int mLidOpenRotation;
Mike Lockwood2d1efbd2009-09-16 12:15:53 -0400576 int mCarDockRotation;
577 int mDeskDockRotation;
Jeff Brownc82c89ed2013-04-17 17:18:15 -0700578 int mUndockedHdmiRotation;
579 int mDemoHdmiRotation;
580 boolean mDemoHdmiRotationLock;
Chong Zhangae6119ff2014-11-11 18:54:39 -0800581 int mDemoRotation;
582 boolean mDemoRotationLock;
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400583
Jeff Browna20dda42014-05-27 20:57:24 -0700584 boolean mWakeGestureEnabledSetting;
585 MyWakeGestureListener mWakeGestureListener;
586
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700587 // Default display does not rotate, apps that require non-default orientation will have to
588 // have the orientation emulated.
589 private boolean mForceDefaultOrientation = false;
590
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400591 int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
592 int mUserRotation = Surface.ROTATION_0;
593
Jeff Brownbcdfc622014-03-06 19:13:04 -0800594 boolean mSupportAutoRotation;
Jeff Brownd3187e32011-09-21 19:26:44 -0700595 int mAllowAllRotations = -1;
Mike Lockwoode9867d22009-09-20 01:59:02 -0400596 boolean mCarDockEnablesAccelerometer;
597 boolean mDeskDockEnablesAccelerometer;
Dianne Hackborn2862fff2009-09-15 22:56:29 -0700598 int mLidKeyboardAccessibility;
599 int mLidNavigationAccessibility;
Edward Savage-Jones7def60d2015-11-13 13:27:03 +0100600 boolean mLidControlsScreenLock;
Jeff Brownc458ce92012-04-30 14:58:40 -0700601 boolean mLidControlsSleep;
Jeff Brown13f00f02014-10-31 14:45:50 -0700602 int mShortPressOnPowerBehavior;
603 int mLongPressOnPowerBehavior;
Michael Kwan57908f02017-11-14 15:27:53 -0800604 int mVeryLongPressOnPowerBehavior;
Jeff Brown13f00f02014-10-31 14:45:50 -0700605 int mDoublePressOnPowerBehavior;
606 int mTriplePressOnPowerBehavior;
Anthony Hugh34f09ca2016-03-04 12:03:37 -0800607 int mLongPressOnBackBehavior;
Filip Gruszczynskia483a1d2015-03-17 19:06:58 +0000608 int mShortPressOnSleepBehavior;
Michael Wright19859762017-09-18 20:57:58 +0100609 int mShortPressOnWindowBehavior;
Adrian Roose94c15c2017-05-09 13:17:54 -0700610 volatile boolean mAwake;
Jeff Brown3ee549c2014-09-22 20:14:39 -0700611 boolean mScreenOnEarly;
612 boolean mScreenOnFully;
613 ScreenOnListener mScreenOnListener;
614 boolean mKeyguardDrawComplete;
615 boolean mWindowManagerDrawComplete;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800616 boolean mOrientationSensorEnabled = false;
617 int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800618 boolean mHasSoftInput = false;
Daniel Sandlerdd73ee42013-10-11 22:19:59 -0400619 boolean mTranslucentDecorEnabled = true;
RoboErik001c59c2015-01-26 15:53:51 -0800620 boolean mUseTvRouting;
Michael Kwan57908f02017-11-14 15:27:53 -0800621 int mVeryLongPressTimeout;
Michael Kwan7f171692018-04-04 14:00:53 -0700622 boolean mAllowStartActivityForLongPressOnPowerDuringSetup;
Craig Mautner967212c2013-04-13 21:10:58 -0700623
Karthik Ravi Shankar86ecf342017-04-28 15:35:58 -0700624 private boolean mHandleVolumeKeysInWM;
625
Jeff Brown70825162012-03-28 17:27:48 -0700626 int mPointerLocationMode = 0; // guarded by mLock
Joe Onorato664644d2011-01-23 17:53:23 -0800627
628 // The last window we were told about in focusChanged.
629 WindowState mFocusedWindow;
Dianne Hackborne0f085d2011-11-30 18:41:15 -0800630 IApplicationToken mFocusedApp;
Joe Onorato664644d2011-01-23 17:53:23 -0800631
Jeff Brown70825162012-03-28 17:27:48 -0700632 PointerLocationView mPointerLocationView;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800633
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800634 // During layout, the layer at which the doc window is placed.
635 int mDockLayer;
Dianne Hackborn5c58de32012-04-28 19:52:37 -0700636 // During layout, this is the layer of the status bar.
637 int mStatusBarLayer;
Dianne Hackborne26ab702011-10-16 13:21:33 -0700638 int mLastSystemUiFlags;
639 // Bits that we are in the process of clearing, so we want to prevent
640 // them from being set by applications until everything has been updated
641 // to have them clear.
642 int mResettingSystemUiFlags = 0;
643 // Bits that we are currently always keeping cleared.
644 int mForceClearedSystemUiFlags = 0;
Jorim Jaggi86905582016-02-09 21:36:09 -0800645 int mLastFullscreenStackSysUiFlags;
646 int mLastDockedStackSysUiFlags;
647 final Rect mNonDockedStackBounds = new Rect();
648 final Rect mDockedStackBounds = new Rect();
649 final Rect mLastNonDockedStackBounds = new Rect();
650 final Rect mLastDockedStackBounds = new Rect();
651
Dianne Hackborn4eff8d32011-11-10 19:38:40 -0800652 // What we last reported to system UI about whether the compatibility
653 // menu needs to be displayed.
654 boolean mLastFocusNeedsMenu = false;
Adrian Roosddc8b272015-05-21 16:28:27 -0700655 // If nonzero, a panic gesture was performed at that time in uptime millis and is still pending.
656 private long mPendingPanicGestureUptime;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700657
Selim Cinekf83e8242015-05-19 18:08:14 -0700658 InputConsumer mInputConsumer = null;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700659
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800660 static final Rect mTmpParentFrame = new Rect();
661 static final Rect mTmpDisplayFrame = new Rect();
Dianne Hackbornc4aad012013-02-22 15:05:25 -0800662 static final Rect mTmpOverscanFrame = new Rect();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800663 static final Rect mTmpContentFrame = new Rect();
664 static final Rect mTmpVisibleFrame = new Rect();
John Spurlock46646232013-09-30 22:32:42 -0400665 static final Rect mTmpDecorFrame = new Rect();
Adrian Roosfa104232014-06-20 16:10:14 -0700666 static final Rect mTmpStableFrame = new Rect();
Dianne Hackborn1f903c32011-09-13 19:18:06 -0700667 static final Rect mTmpNavigationFrame = new Rect();
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700668 static final Rect mTmpOutsetFrame = new Rect();
Adrian Roos5ed644f2018-03-19 17:01:05 +0100669 private static final Rect mTmpDisplayCutoutSafeExceptMaybeBarsRect = new Rect();
Jorim Jaggi23bf5462016-05-13 15:24:39 -0700670 private static final Rect mTmpRect = new Rect();
Craig Mautner967212c2013-04-13 21:10:58 -0700671
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800672 WindowState mTopFullscreenOpaqueWindowState;
Adrian Rooscd3884d2015-02-18 17:25:23 +0100673 WindowState mTopFullscreenOpaqueOrDimmingWindowState;
Jorim Jaggi86905582016-02-09 21:36:09 -0800674 WindowState mTopDockedOpaqueWindowState;
675 WindowState mTopDockedOpaqueOrDimmingWindowState;
Joe Onorato93056472010-09-10 10:30:46 -0400676 boolean mTopIsFullscreen;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800677 boolean mForceStatusBar;
Dianne Hackborn4c1e3182012-10-05 18:37:54 -0700678 boolean mForceStatusBarFromKeyguard;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700679 private boolean mForceStatusBarTransparent;
Yorke Lee9b2ffb32016-03-07 20:42:01 -0800680 int mNavBarOpacityMode = NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED;
Dianne Hackborn891d3fb2013-01-09 18:31:37 -0800681 boolean mForcingShowNavBar;
682 int mForcingShowNavBarLayer;
Craig Mautnerad09bcc2012-10-08 13:33:11 -0700683
Jorim Jaggife762342016-10-13 14:33:27 +0200684 private boolean mPendingKeyguardOccluded;
685 private boolean mKeyguardOccludedChanged;
Yoshiaki Nakae1bdfc822017-09-15 15:24:34 +0900686 private boolean mNotifyUserActivity;
Craig Mautnerc9457fa2014-06-06 14:27:48 -0700687
Dianne Hackborn7ad44382012-10-18 17:46:00 -0700688 boolean mShowingDream;
Jorim Jaggi77e10432016-10-26 17:43:56 -0700689 private boolean mLastShowingDream;
Dianne Hackborn7ad44382012-10-18 17:46:00 -0700690 boolean mDreamingLockscreen;
Jeff Brown061ea992015-04-17 19:55:47 -0700691 boolean mDreamingSleepTokenNeeded;
Jorim Jaggif12ec0f2017-08-23 16:14:10 +0200692 private boolean mWindowSleepTokenNeeded;
693 private boolean mLastWindowSleepTokenNeeded;
694
695 @GuardedBy("mHandler")
696 private SleepToken mWindowSleepToken;
697
Jeff Brown061ea992015-04-17 19:55:47 -0700698 SleepToken mDreamingSleepToken;
Jeff Brown48d1b142015-06-10 16:36:03 -0700699 SleepToken mScreenOffSleepToken;
Jim Millerab954542014-10-10 18:21:49 -0700700 volatile boolean mKeyguardOccluded;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800701 boolean mHomePressed;
Jeff Browncaca8812013-05-09 13:34:33 -0700702 boolean mHomeConsumed;
703 boolean mHomeDoubleTapPending;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800704 Intent mHomeIntent;
Dianne Hackborn39c2d712009-09-22 11:41:31 -0700705 Intent mCarDockIntent;
706 Intent mDeskDockIntent;
Zak Cohendb6ca492017-01-26 14:09:00 -0800707 Intent mVrHeadsetHomeIntent;
Jeff Brownfd23e3e2012-05-09 13:34:28 -0700708 boolean mSearchKeyShortcutPending;
709 boolean mConsumeSearchKeyUp;
Michael Wright6a62e552014-06-03 19:19:48 -0700710 boolean mPendingMetaAction;
Andrii Kulian112d0562016-03-08 10:44:22 -0800711 boolean mPendingCapsLockToggle;
712 int mMetaState;
713 int mInitialMetaState;
Jorim Jaggi0ffd49c2016-02-12 15:04:21 -0800714 boolean mForceShowSystemBars;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800715
Mike Lockwood28569302010-01-28 11:54:40 -0500716 // support for activating the lock screen while the screen is on
717 boolean mAllowLockscreenWhenOn;
718 int mLockScreenTimeout;
719 boolean mLockScreenTimerActive;
720
David Brownbaf8d092010-03-08 21:52:59 -0800721 // Behavior of ENDCALL Button. (See Settings.System.END_BUTTON_BEHAVIOR.)
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800722 int mEndcallBehavior;
David Brownbaf8d092010-03-08 21:52:59 -0800723
724 // Behavior of POWER button while in-call and screen on.
725 // (See Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR.)
726 int mIncallPowerBehavior;
727
Bryce Leedb776ce2016-09-03 15:02:00 -0700728 // Behavior of Back button while in-call and screen on
729 int mIncallBackBehavior;
730
Mike Digmane14e6632018-01-11 10:43:08 -0800731 // Behavior of rotation suggestions. (See Settings.Secure.SHOW_ROTATION_SUGGESTION)
732 int mShowRotationSuggestions;
733
Siarhei Vishniakoue5e0d9f2018-03-05 20:09:08 -0800734 // Whether system navigation keys are enabled
735 boolean mSystemNavigationKeysEnabled;
736
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700737 Display mDisplay;
738
Dianne Hackborn9d132642011-04-21 17:26:39 -0700739 int mLandscapeRotation = 0; // default landscape rotation
740 int mSeascapeRotation = 0; // "other" landscape rotation, 180 degrees from mLandscapeRotation
741 int mPortraitRotation = 0; // default portrait rotation
742 int mUpsideDownRotation = 0; // "other" portrait rotation
Mitsuru Oshima831d0d92009-06-16 18:27:18 -0700743
Joe Onorato46b0d682010-11-22 17:37:27 -0800744 // What we do when the user long presses on home
Jeff Browncaca8812013-05-09 13:34:33 -0700745 private int mLongPressOnHomeBehavior;
746
747 // What we do when the user double-taps on home
748 private int mDoubleTapOnHomeBehavior;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800749
Bryce Lee584a4452014-10-21 15:55:55 -0700750 // Allowed theater mode wake actions
751 private boolean mAllowTheaterModeWakeFromKey;
752 private boolean mAllowTheaterModeWakeFromPowerKey;
753 private boolean mAllowTheaterModeWakeFromMotion;
Bryce Lee812d7022014-11-10 13:33:28 -0800754 private boolean mAllowTheaterModeWakeFromMotionWhenNotDreaming;
Bryce Lee584a4452014-10-21 15:55:55 -0700755 private boolean mAllowTheaterModeWakeFromCameraLens;
756 private boolean mAllowTheaterModeWakeFromLidSwitch;
757 private boolean mAllowTheaterModeWakeFromWakeGesture;
758
Bryce Leed3b28402015-03-09 15:49:13 +0000759 // Whether to support long press from power button in non-interactive mode
760 private boolean mSupportLongPressPowerWhenNonInteractive;
761
Bryce Lee55e846d2014-11-04 12:43:44 -0800762 // Whether to go to sleep entering theater mode from power button
763 private boolean mGoToSleepOnButtonPressTheaterMode;
764
Winson Chung9112ec32011-06-27 13:15:32 -0700765 // Screenshot trigger states
Jeff Brownd5bb82d2011-10-12 13:57:59 -0700766 // Time to volume and power must be pressed within this interval of each other.
767 private static final long SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS = 150;
Winson Chung1cea2f32012-10-08 20:42:01 -0700768 // Increase the chord delay when taking a screenshot from the keyguard
769 private static final float KEYGUARD_SCREENSHOT_CHORD_DELAY_MULTIPLIER = 2.5f;
Christopher Tatee90585f2012-03-05 18:56:25 -0800770 private boolean mScreenshotChordEnabled;
Jeff Brown13f00f02014-10-31 14:45:50 -0700771 private boolean mScreenshotChordVolumeDownKeyTriggered;
772 private long mScreenshotChordVolumeDownKeyTime;
773 private boolean mScreenshotChordVolumeDownKeyConsumed;
Phil Weaver106fe732016-11-22 18:18:39 -0800774 private boolean mA11yShortcutChordVolumeUpKeyTriggered;
775 private long mA11yShortcutChordVolumeUpKeyTime;
776 private boolean mA11yShortcutChordVolumeUpKeyConsumed;
777
Jeff Brown13f00f02014-10-31 14:45:50 -0700778 private boolean mScreenshotChordPowerKeyTriggered;
779 private long mScreenshotChordPowerKeyTime;
Winson Chung9112ec32011-06-27 13:15:32 -0700780
Mike Digman55272862018-02-20 14:35:17 -0800781 // Ringer toggle should reuse timing and triggering from screenshot power and a11y vol up
782 private int mRingerToggleChord = VOLUME_HUSH_OFF;
783
Dmitri Plotnikov82e6dfc2017-02-24 18:10:54 -0800784 private static final long BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS = 1000;
785
786 private boolean mBugreportTvKey1Pressed;
787 private boolean mBugreportTvKey2Pressed;
788 private boolean mBugreportTvScheduled;
789
Sujith Ramakrishnan6bed9bd2017-04-26 12:33:37 -0700790 private boolean mAccessibilityTvKey1Pressed;
791 private boolean mAccessibilityTvKey2Pressed;
792 private boolean mAccessibilityTvScheduled;
793
Michael Wrightb854e242013-02-05 17:54:02 -0800794 /* The number of steps between min and max brightness */
795 private static final int BRIGHTNESS_STEPS = 10;
796
Christopher Tate5e08af02012-09-21 17:17:22 -0700797 SettingsObserver mSettingsObserver;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800798 ShortcutManager mShortcutManager;
799 PowerManager.WakeLock mBroadcastWakeLock;
Jeff Brown13f00f02014-10-31 14:45:50 -0700800 PowerManager.WakeLock mPowerKeyWakeLock;
Jeff Brown40013652012-05-16 21:22:36 -0700801 boolean mHavePendingMediaKeyRepeatWithWakeLock;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800802
Craig Mautnerd625ab22013-09-06 13:40:31 -0700803 private int mCurrentUserId;
804
Phil Weaverd7551602018-02-15 15:01:04 -0800805 /* Whether accessibility is magnifying the screen */
806 private boolean mScreenMagnificationActive;
807
Justin Kohd378ad72013-04-01 12:18:26 -0700808 // Maps global key codes to the components that will handle them.
809 private GlobalKeyManager mGlobalKeyManager;
810
Jeff Brownfd23e3e2012-05-09 13:34:28 -0700811 // Fallback actions by key code.
812 private final SparseArray<KeyCharacterMap.FallbackAction> mFallbackActions =
813 new SparseArray<KeyCharacterMap.FallbackAction>();
Jeff Brown49ed71d2010-12-06 17:13:33 -0800814
Jorim Jaggi76a16232014-08-08 17:00:47 +0200815 private final LogDecelerateInterpolator mLogDecelerateInterpolator
816 = new LogDecelerateInterpolator(100, 0);
817
Jorim Jaggif1cdf952016-04-05 21:41:06 -0700818 private final MutableBoolean mTmpBoolean = new MutableBoolean(false);
Wale Ogunwale6b15ea52016-04-04 07:28:27 -0700819
Jeff Brown70825162012-03-28 17:27:48 -0700820 private static final int MSG_ENABLE_POINTER_LOCATION = 1;
821 private static final int MSG_DISABLE_POINTER_LOCATION = 2;
Jeff Brown40013652012-05-16 21:22:36 -0700822 private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
823 private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
Craig Mautner8a0da012014-05-31 15:13:37 -0700824 private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5;
825 private static final int MSG_KEYGUARD_DRAWN_TIMEOUT = 6;
826 private static final int MSG_WINDOW_MANAGER_DRAWN_COMPLETE = 7;
Craig Mautner84984fa2014-06-19 11:19:20 -0700827 private static final int MSG_DISPATCH_SHOW_RECENTS = 9;
Alan Viverettee34560b22014-07-10 14:50:06 -0700828 private static final int MSG_DISPATCH_SHOW_GLOBAL_ACTIONS = 10;
Craig Mautnera631d492014-08-05 15:16:01 -0700829 private static final int MSG_HIDE_BOOT_MESSAGE = 11;
Michael Wright869a67c2014-08-26 19:33:06 -0700830 private static final int MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK = 12;
Jeff Brown13f00f02014-10-31 14:45:50 -0700831 private static final int MSG_POWER_DELAYED_PRESS = 13;
832 private static final int MSG_POWER_LONG_PRESS = 14;
Jeff Brown061ea992015-04-17 19:55:47 -0700833 private static final int MSG_UPDATE_DREAMING_SLEEP_TOKEN = 15;
Jun Mukaid2e7e352015-07-22 17:14:02 -0700834 private static final int MSG_REQUEST_TRANSIENT_BARS = 16;
Winson Chungac52f282017-03-30 14:44:52 -0700835 private static final int MSG_SHOW_PICTURE_IN_PICTURE_MENU = 17;
Anthony Hugh34f09ca2016-03-04 12:03:37 -0800836 private static final int MSG_BACK_LONG_PRESS = 18;
Chong Zhang9f7fb092016-05-20 17:03:08 -0700837 private static final int MSG_DISPOSE_INPUT_CONSUMER = 19;
Erik Wolsheimerbb978792017-12-11 13:45:21 -0800838 private static final int MSG_ACCESSIBILITY_SHORTCUT = 20;
839 private static final int MSG_BUGREPORT_TV = 21;
840 private static final int MSG_ACCESSIBILITY_TV = 22;
841 private static final int MSG_DISPATCH_BACK_KEY_TO_AUTOFILL = 23;
842 private static final int MSG_SYSTEM_KEY_PRESS = 24;
843 private static final int MSG_HANDLE_ALL_APPS = 25;
844 private static final int MSG_LAUNCH_ASSIST = 26;
845 private static final int MSG_LAUNCH_ASSIST_LONG_PRESS = 27;
846 private static final int MSG_POWER_VERY_LONG_PRESS = 28;
Yoshiaki Nakae1bdfc822017-09-15 15:24:34 +0900847 private static final int MSG_NOTIFY_USER_ACTIVITY = 29;
Mike Digman55272862018-02-20 14:35:17 -0800848 private static final int MSG_RINGER_TOGGLE_CHORD = 30;
Jun Mukaid2e7e352015-07-22 17:14:02 -0700849
850 private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
851 private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
Jeff Brown70825162012-03-28 17:27:48 -0700852
853 private class PolicyHandler extends Handler {
854 @Override
855 public void handleMessage(Message msg) {
856 switch (msg.what) {
857 case MSG_ENABLE_POINTER_LOCATION:
858 enablePointerLocation();
859 break;
860 case MSG_DISABLE_POINTER_LOCATION:
861 disablePointerLocation();
862 break;
Jeff Brown40013652012-05-16 21:22:36 -0700863 case MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK:
864 dispatchMediaKeyWithWakeLock((KeyEvent)msg.obj);
865 break;
866 case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK:
867 dispatchMediaKeyRepeatWithWakeLock((KeyEvent)msg.obj);
868 break;
Craig Mautner84984fa2014-06-19 11:19:20 -0700869 case MSG_DISPATCH_SHOW_RECENTS:
Winson Chungdff7a732017-12-11 12:17:06 -0800870 showRecentApps(false);
Craig Mautner84984fa2014-06-19 11:19:20 -0700871 break;
Alan Viverettee34560b22014-07-10 14:50:06 -0700872 case MSG_DISPATCH_SHOW_GLOBAL_ACTIONS:
873 showGlobalActionsInternal();
874 break;
Craig Mautner8a0da012014-05-31 15:13:37 -0700875 case MSG_KEYGUARD_DRAWN_COMPLETE:
876 if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mKeyguardDrawComplete");
Jeff Brown36c4db82014-09-19 12:05:31 -0700877 finishKeyguardDrawn();
Craig Mautner8a0da012014-05-31 15:13:37 -0700878 break;
879 case MSG_KEYGUARD_DRAWN_TIMEOUT:
880 Slog.w(TAG, "Keyguard drawn timeout. Setting mKeyguardDrawComplete");
Jeff Brown36c4db82014-09-19 12:05:31 -0700881 finishKeyguardDrawn();
Craig Mautner8a0da012014-05-31 15:13:37 -0700882 break;
883 case MSG_WINDOW_MANAGER_DRAWN_COMPLETE:
884 if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mWindowManagerDrawComplete");
Jeff Brown36c4db82014-09-19 12:05:31 -0700885 finishWindowsDrawn();
Craig Mautner8a0da012014-05-31 15:13:37 -0700886 break;
Craig Mautnera631d492014-08-05 15:16:01 -0700887 case MSG_HIDE_BOOT_MESSAGE:
888 handleHideBootMessage();
889 break;
Siarhei Vishniakou191cf1b2017-08-17 16:17:22 -0700890 case MSG_LAUNCH_ASSIST:
891 final int deviceId = msg.arg1;
892 final String hint = (String) msg.obj;
893 launchAssistAction(hint, deviceId);
894 break;
895 case MSG_LAUNCH_ASSIST_LONG_PRESS:
896 launchAssistLongPressAction();
897 break;
Michael Wright869a67c2014-08-26 19:33:06 -0700898 case MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK:
Siarhei Vishniakou191cf1b2017-08-17 16:17:22 -0700899 launchVoiceAssistWithWakeLock();
Michael Wright869a67c2014-08-26 19:33:06 -0700900 break;
Jeff Brown13f00f02014-10-31 14:45:50 -0700901 case MSG_POWER_DELAYED_PRESS:
902 powerPress((Long)msg.obj, msg.arg1 != 0, msg.arg2);
903 finishPowerKeyPress();
904 break;
905 case MSG_POWER_LONG_PRESS:
906 powerLongPress();
907 break;
Michael Kwan57908f02017-11-14 15:27:53 -0800908 case MSG_POWER_VERY_LONG_PRESS:
909 powerVeryLongPress();
910 break;
Jeff Brown061ea992015-04-17 19:55:47 -0700911 case MSG_UPDATE_DREAMING_SLEEP_TOKEN:
912 updateDreamingSleepToken(msg.arg1 != 0);
913 break;
Jun Mukaid2e7e352015-07-22 17:14:02 -0700914 case MSG_REQUEST_TRANSIENT_BARS:
915 WindowState targetBar = (msg.arg1 == MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS) ?
916 mStatusBar : mNavigationBar;
917 if (targetBar != null) {
918 requestTransientBars(targetBar);
919 }
920 break;
Winson Chungac52f282017-03-30 14:44:52 -0700921 case MSG_SHOW_PICTURE_IN_PICTURE_MENU:
922 showPictureInPictureMenuInternal();
Jaewan Kimc552b042016-01-18 16:08:45 +0900923 break;
Anthony Hugh34f09ca2016-03-04 12:03:37 -0800924 case MSG_BACK_LONG_PRESS:
925 backLongPress();
926 break;
Chong Zhang9f7fb092016-05-20 17:03:08 -0700927 case MSG_DISPOSE_INPUT_CONSUMER:
928 disposeInputConsumer((InputConsumer) msg.obj);
929 break;
Phil Weaver106fe732016-11-22 18:18:39 -0800930 case MSG_ACCESSIBILITY_SHORTCUT:
931 accessibilityShortcutActivated();
932 break;
Dmitri Plotnikov82e6dfc2017-02-24 18:10:54 -0800933 case MSG_BUGREPORT_TV:
934 takeBugreport();
935 break;
Sujith Ramakrishnan6bed9bd2017-04-26 12:33:37 -0700936 case MSG_ACCESSIBILITY_TV:
937 if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(false)) {
938 accessibilityShortcutActivated();
939 }
940 break;
Felipe Leme5f978802017-06-08 13:01:13 -0700941 case MSG_DISPATCH_BACK_KEY_TO_AUTOFILL:
942 mAutofillManagerInternal.onBackKeyPressed();
943 break;
Philip Quinn4b5b3c62017-07-20 21:07:58 -0700944 case MSG_SYSTEM_KEY_PRESS:
945 sendSystemKeyToStatusBar(msg.arg1);
946 break;
Sujith Ramakrishnanf8942c02017-07-18 18:35:14 -0700947 case MSG_HANDLE_ALL_APPS:
948 launchAllAppsAction();
949 break;
Yoshiaki Nakae1bdfc822017-09-15 15:24:34 +0900950 case MSG_NOTIFY_USER_ACTIVITY:
951 removeMessages(MSG_NOTIFY_USER_ACTIVITY);
952 Intent intent = new Intent(ACTION_USER_ACTIVITY_NOTIFICATION);
953 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
954 mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
955 android.Manifest.permission.USER_ACTIVITY);
Mike Digman55272862018-02-20 14:35:17 -0800956 case MSG_RINGER_TOGGLE_CHORD:
957 handleRingerChordGesture();
Yoshiaki Nakae1bdfc822017-09-15 15:24:34 +0900958 break;
Jeff Brown70825162012-03-28 17:27:48 -0700959 }
960 }
961 }
962
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -0800963 private UEventObserver mHDMIObserver = new UEventObserver() {
964 @Override
965 public void onUEvent(UEventObserver.UEvent event) {
966 setHdmiPlugged("1".equals(event.get("SWITCH_STATE")));
967 }
968 };
969
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800970 class SettingsObserver extends ContentObserver {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800971 SettingsObserver(Handler handler) {
972 super(handler);
973 }
David Brownbaf8d092010-03-08 21:52:59 -0800974
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800975 void observe() {
Christopher Tate5e08af02012-09-21 17:17:22 -0700976 // Observe all users' changes
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800977 ContentResolver resolver = mContext.getContentResolver();
978 resolver.registerContentObserver(Settings.System.getUriFor(
Christopher Tate5e08af02012-09-21 17:17:22 -0700979 Settings.System.END_BUTTON_BEHAVIOR), false, this,
980 UserHandle.USER_ALL);
David Brownbaf8d092010-03-08 21:52:59 -0800981 resolver.registerContentObserver(Settings.Secure.getUriFor(
Christopher Tate5e08af02012-09-21 17:17:22 -0700982 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR), false, this,
983 UserHandle.USER_ALL);
Jeff Browna20dda42014-05-27 20:57:24 -0700984 resolver.registerContentObserver(Settings.Secure.getUriFor(
Bryce Leedb776ce2016-09-03 15:02:00 -0700985 Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR), false, this,
986 UserHandle.USER_ALL);
987 resolver.registerContentObserver(Settings.Secure.getUriFor(
Jeff Browna20dda42014-05-27 20:57:24 -0700988 Settings.Secure.WAKE_GESTURE_ENABLED), false, this,
989 UserHandle.USER_ALL);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800990 resolver.registerContentObserver(Settings.System.getUriFor(
Christopher Tate5e08af02012-09-21 17:17:22 -0700991 Settings.System.ACCELEROMETER_ROTATION), false, this,
992 UserHandle.USER_ALL);
Mike Lockwood28569302010-01-28 11:54:40 -0500993 resolver.registerContentObserver(Settings.System.getUriFor(
Christopher Tate5e08af02012-09-21 17:17:22 -0700994 Settings.System.USER_ROTATION), false, this,
995 UserHandle.USER_ALL);
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400996 resolver.registerContentObserver(Settings.System.getUriFor(
Christopher Tate5e08af02012-09-21 17:17:22 -0700997 Settings.System.SCREEN_OFF_TIMEOUT), false, this,
998 UserHandle.USER_ALL);
Dianne Hackbornc777e072010-02-12 13:07:59 -0800999 resolver.registerContentObserver(Settings.System.getUriFor(
Christopher Tate5e08af02012-09-21 17:17:22 -07001000 Settings.System.POINTER_LOCATION), false, this,
1001 UserHandle.USER_ALL);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001002 resolver.registerContentObserver(Settings.Secure.getUriFor(
Christopher Tate5e08af02012-09-21 17:17:22 -07001003 Settings.Secure.DEFAULT_INPUT_METHOD), false, this,
1004 UserHandle.USER_ALL);
John Spurlockd9b70bd2014-02-06 17:02:44 -05001005 resolver.registerContentObserver(Settings.Secure.getUriFor(
John Spurlockf1a36642013-10-12 17:50:42 -04001006 Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS), false, this,
Christopher Tate5e08af02012-09-21 17:17:22 -07001007 UserHandle.USER_ALL);
Mike Digmane14e6632018-01-11 10:43:08 -08001008 resolver.registerContentObserver(Settings.Secure.getUriFor(
1009 Settings.Secure.SHOW_ROTATION_SUGGESTIONS), false, this,
1010 UserHandle.USER_ALL);
Mike Digman55272862018-02-20 14:35:17 -08001011 resolver.registerContentObserver(Settings.Secure.getUriFor(
1012 Settings.Secure.VOLUME_HUSH_GESTURE), false, this,
1013 UserHandle.USER_ALL);
John Spurlockc6d1c602014-01-17 15:22:06 -05001014 resolver.registerContentObserver(Settings.Global.getUriFor(
1015 Settings.Global.POLICY_CONTROL), false, this,
1016 UserHandle.USER_ALL);
Kevin Chynf823d3e2018-03-20 14:42:39 -07001017 resolver.registerContentObserver(Settings.Secure.getUriFor(
Siarhei Vishniakoue5e0d9f2018-03-05 20:09:08 -08001018 Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED), false, this,
1019 UserHandle.USER_ALL);
Dianne Hackbornc777e072010-02-12 13:07:59 -08001020 updateSettings();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001021 }
1022
1023 @Override public void onChange(boolean selfChange) {
Dianne Hackbornc777e072010-02-12 13:07:59 -08001024 updateSettings();
Jeff Brown01a98dd2011-09-20 15:08:29 -07001025 updateRotation(false);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001026 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001027 }
Craig Mautner967212c2013-04-13 21:10:58 -07001028
Jeff Browna20dda42014-05-27 20:57:24 -07001029 class MyWakeGestureListener extends WakeGestureListener {
1030 MyWakeGestureListener(Context context, Handler handler) {
1031 super(context, handler);
1032 }
1033
1034 @Override
1035 public void onWakeUp() {
1036 synchronized (mLock) {
1037 if (shouldEnableWakeGestureLp()) {
Jeff Browne07b94b2014-06-18 15:56:27 -07001038 performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001039 wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromWakeGesture,
1040 "android.policy:GESTURE");
Jeff Browna20dda42014-05-27 20:57:24 -07001041 }
1042 }
1043 }
1044 }
1045
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001046 class MyOrientationListener extends WindowOrientationListener {
Mike Digmane14e6632018-01-11 10:43:08 -08001047
1048 private SparseArray<Runnable> mRunnableCache;
1049
1050 MyOrientationListener(Context context, Handler handler) {
1051 super(context, handler);
1052 mRunnableCache = new SparseArray<>(5);
1053 }
1054
1055 private class UpdateRunnable implements Runnable {
1056 private final int mRotation;
1057 UpdateRunnable(int rotation) {
1058 mRotation = rotation;
1059 }
1060
Chong Zhang5aaa0b32015-08-28 10:22:36 -07001061 @Override
1062 public void run() {
Tim Murray1f407642015-10-01 17:07:12 -07001063 // send interaction hint to improve redraw performance
Ruchi Kandoi0d434042016-10-03 09:12:02 -07001064 mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0);
Mike Digmanbe875db2018-01-26 11:13:23 -08001065 if (isRotationChoicePossible(mCurrentAppOrientation)) {
Mike Digmane0777312018-01-19 12:41:51 -08001066 final boolean isValid = isValidRotationChoice(mCurrentAppOrientation,
1067 mRotation);
1068 sendProposedRotationChangeToStatusBarInternal(mRotation, isValid);
Mike Digmane14e6632018-01-11 10:43:08 -08001069 } else {
1070 updateRotation(false);
1071 }
Chong Zhang5aaa0b32015-08-28 10:22:36 -07001072 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001073 }
Craig Mautner967212c2013-04-13 21:10:58 -07001074
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001075 @Override
Jeff Brownc0347aa2011-09-23 17:26:09 -07001076 public void onProposedRotationChanged(int rotation) {
Craig Mautnereda67292013-04-28 13:50:14 -07001077 if (localLOGV) Slog.v(TAG, "onProposedRotationChanged, rotation=" + rotation);
Mike Digmane14e6632018-01-11 10:43:08 -08001078 Runnable r = mRunnableCache.get(rotation, null);
1079 if (r == null){
1080 r = new UpdateRunnable(rotation);
1081 mRunnableCache.put(rotation, r);
1082 }
1083 mHandler.post(r);
Jeff Brown01a98dd2011-09-20 15:08:29 -07001084 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001085 }
1086 MyOrientationListener mOrientationListener;
1087
Santos Cordonc09d89c2017-04-13 16:12:02 -07001088 final IPersistentVrStateCallbacks mPersistentVrModeListener =
1089 new IPersistentVrStateCallbacks.Stub() {
1090 @Override
1091 public void onPersistentVrStateChanged(boolean enabled) {
1092 mPersistentVrModeEnabled = enabled;
1093 }
1094 };
1095
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01001096 private final StatusBarController mStatusBarController = new StatusBarController();
John Spurlock5b9145b2013-08-20 15:13:47 -04001097
John Spurlock27735a42013-08-14 17:57:38 -04001098 private final BarController mNavigationBarController = new BarController("NavigationBar",
John Spurlock5b9145b2013-08-20 15:13:47 -04001099 View.NAVIGATION_BAR_TRANSIENT,
1100 View.NAVIGATION_BAR_UNHIDE,
John Spurlockbd957402013-10-03 11:38:39 -04001101 View.NAVIGATION_BAR_TRANSLUCENT,
1102 StatusBarManager.WINDOW_NAVIGATION_BAR,
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00001103 FLAG_TRANSLUCENT_NAVIGATION,
Jorim Jaggi4fa78922015-11-30 17:13:56 -08001104 View.NAVIGATION_BAR_TRANSPARENT);
John Spurlock5b9145b2013-08-20 15:13:47 -04001105
Casey Burkhardt048c2bc2016-12-08 16:09:20 -08001106 private final BarController.OnBarVisibilityChangedListener mNavBarVisibilityListener =
1107 new BarController.OnBarVisibilityChangedListener() {
1108 @Override
1109 public void onBarVisibilityChanged(boolean visible) {
Casey Burkhardt469a2082017-06-13 20:12:42 -07001110 mAccessibilityManager.notifyAccessibilityButtonVisibilityChanged(visible);
Casey Burkhardt048c2bc2016-12-08 16:09:20 -08001111 }
1112 };
1113
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02001114 private final Runnable mAcquireSleepTokenRunnable = () -> {
1115 if (mWindowSleepToken != null) {
1116 return;
1117 }
1118 mWindowSleepToken = mActivityManagerInternal.acquireSleepToken("WindowSleepToken",
1119 DEFAULT_DISPLAY);
1120 };
1121
1122 private final Runnable mReleaseSleepTokenRunnable = () -> {
1123 if (mWindowSleepToken == null) {
1124 return;
1125 }
1126 mWindowSleepToken.release();
1127 mWindowSleepToken = null;
1128 };
1129
John Spurlockf1a36642013-10-12 17:50:42 -04001130 private ImmersiveModeConfirmation mImmersiveModeConfirmation;
John Spurlock32beb2c2013-03-11 10:16:47 -04001131
Adrian Roose1856fe2017-11-24 19:39:12 +01001132 @VisibleForTesting
1133 SystemGesturesPointerEventListener mSystemGestures;
John Spurlock32beb2c2013-03-11 10:16:47 -04001134
Mike Digman55272862018-02-20 14:35:17 -08001135 private void handleRingerChordGesture() {
1136 if (mRingerToggleChord == VOLUME_HUSH_OFF) {
1137 return;
1138 }
1139 getAudioManagerInternal();
1140 mAudioManagerInternal.silenceRingerModeInternal("volume_hush");
1141 }
1142
Dianne Hackborn42e620c2012-06-24 13:20:51 -07001143 IStatusBarService getStatusBarService() {
1144 synchronized (mServiceAquireLock) {
1145 if (mStatusBarService == null) {
1146 mStatusBarService = IStatusBarService.Stub.asInterface(
1147 ServiceManager.getService("statusbar"));
1148 }
1149 return mStatusBarService;
1150 }
1151 }
1152
Jorim Jaggi86905582016-02-09 21:36:09 -08001153 StatusBarManagerInternal getStatusBarManagerInternal() {
1154 synchronized (mServiceAquireLock) {
1155 if (mStatusBarManagerInternal == null) {
1156 mStatusBarManagerInternal =
1157 LocalServices.getService(StatusBarManagerInternal.class);
1158 }
1159 return mStatusBarManagerInternal;
1160 }
1161 }
1162
Mike Digman55272862018-02-20 14:35:17 -08001163 AudioManagerInternal getAudioManagerInternal() {
1164 synchronized (mServiceAquireLock) {
1165 if (mAudioManagerInternal == null) {
1166 mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
1167 }
1168 return mAudioManagerInternal;
1169 }
1170 }
1171
Suchi Amalapurapua9e1b162009-03-24 22:24:47 -07001172 /*
1173 * We always let the sensor be switched on by default except when
1174 * the user has explicitly disabled sensor based rotation or when the
1175 * screen is switched off.
1176 */
The Android Open Source Project0727d222009-03-11 12:11:58 -07001177 boolean needSensorRunningLp() {
Jeff Brownbcdfc622014-03-06 19:13:04 -08001178 if (mSupportAutoRotation) {
1179 if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
1180 || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
1181 || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
1182 || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
1183 // If the application has explicitly requested to follow the
1184 // orientation, then we need to turn the sensor on.
1185 return true;
1186 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001187 }
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001188 if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) ||
Jeff Brown1a693182011-11-08 14:44:16 -08001189 (mDeskDockEnablesAccelerometer && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK
1190 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
1191 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK))) {
Mike Lockwoode9867d22009-09-20 01:59:02 -04001192 // enable accelerometer if we are docked in a dock that enables accelerometer
1193 // orientation management,
1194 return true;
1195 }
Jeff Brown207673cd2012-06-05 17:47:11 -07001196 if (mUserRotationMode == USER_ROTATION_LOCKED) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001197 // If the setting for using the sensor by default is enabled, then
1198 // we will always leave it on. Note that the user could go to
1199 // a window that forces an orientation that does not use the
1200 // sensor and in theory we could turn it off... however, when next
1201 // turning it on we won't have a good value for the current
1202 // orientation for a little bit, which can cause orientation
1203 // changes to lag, so we'd like to keep it always on. (It will
1204 // still be turned off when the screen is off.)
Mike Digmane14e6632018-01-11 10:43:08 -08001205
1206 // When locked we can provide rotation suggestions users can approve to change the
1207 // current screen rotation. To do this the sensor needs to be running.
1208 return mSupportAutoRotation &&
1209 mShowRotationSuggestions == Settings.Secure.SHOW_ROTATION_SUGGESTIONS_ENABLED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001210 }
Jeff Brownbcdfc622014-03-06 19:13:04 -08001211 return mSupportAutoRotation;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001212 }
Craig Mautner46ac6fa2013-08-01 10:06:34 -07001213
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001214 /*
1215 * Various use cases for invoking this function
1216 * screen turning off, should always disable listeners if already enabled
Craig Mautner46ac6fa2013-08-01 10:06:34 -07001217 * screen turned on and current app has sensor based orientation, enable listeners
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001218 * if not already enabled
1219 * screen turned on and current app does not have sensor orientation, disable listeners if
1220 * already enabled
1221 * screen turning on and current app has sensor based orientation, enable listeners if needed
1222 * screen turning on and current app has nosensor based orientation, do nothing
1223 */
The Android Open Source Project0727d222009-03-11 12:11:58 -07001224 void updateOrientationListenerLp() {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001225 if (!mOrientationListener.canDetectOrientation()) {
1226 // If sensor is turned off or nonexistent for some reason
1227 return;
1228 }
Stefan Kuhne9326dc12015-06-12 09:25:32 -10001229 // Could have been invoked due to screen turning on or off or
1230 // change of the currently visible window's orientation.
Jeff Brown3ee549c2014-09-22 20:14:39 -07001231 if (localLOGV) Slog.v(TAG, "mScreenOnEarly=" + mScreenOnEarly
1232 + ", mAwake=" + mAwake + ", mCurrentAppOrientation=" + mCurrentAppOrientation
Stefan Kuhne9326dc12015-06-12 09:25:32 -10001233 + ", mOrientationSensorEnabled=" + mOrientationSensorEnabled
1234 + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete
1235 + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
Wale Ogunwalebfa81ad2017-05-24 15:14:42 -07001236
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001237 boolean disable = true;
Stefan Kuhne9326dc12015-06-12 09:25:32 -10001238 // Note: We postpone the rotating of the screen until the keyguard as well as the
Wale Ogunwalebfa81ad2017-05-24 15:14:42 -07001239 // window manager have reported a draw complete or the keyguard is going away in dismiss
1240 // mode.
Andrii Kulian92c9a942017-10-10 00:41:41 -07001241 if (mScreenOnEarly && mAwake && ((mKeyguardDrawComplete && mWindowManagerDrawComplete))) {
The Android Open Source Project0727d222009-03-11 12:11:58 -07001242 if (needSensorRunningLp()) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001243 disable = false;
1244 //enable listener if not already enabled
The Android Open Source Project0727d222009-03-11 12:11:58 -07001245 if (!mOrientationSensorEnabled) {
Wale Ogunwalebfa81ad2017-05-24 15:14:42 -07001246 // Don't clear the current sensor orientation if the keyguard is going away in
1247 // dismiss mode. This allows window manager to use the last sensor reading to
1248 // determine the orientation vs. falling back to the last known orientation if
1249 // the sensor reading was cleared which can cause it to relaunch the app that
1250 // will show in the wrong orientation first before correcting leading to app
1251 // launch delays.
Andrii Kulian92c9a942017-10-10 00:41:41 -07001252 mOrientationListener.enable(true /* clearCurrentRotation */);
Craig Mautnereda67292013-04-28 13:50:14 -07001253 if(localLOGV) Slog.v(TAG, "Enabling listeners");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001254 mOrientationSensorEnabled = true;
1255 }
Craig Mautner46ac6fa2013-08-01 10:06:34 -07001256 }
1257 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001258 //check if sensors need to be disabled
The Android Open Source Project0727d222009-03-11 12:11:58 -07001259 if (disable && mOrientationSensorEnabled) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001260 mOrientationListener.disable();
Craig Mautnereda67292013-04-28 13:50:14 -07001261 if(localLOGV) Slog.v(TAG, "Disabling listeners");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001262 mOrientationSensorEnabled = false;
1263 }
1264 }
1265
Anthony Hugh96e9cc52016-07-12 15:17:24 -07001266 private void interceptBackKeyDown() {
Nimrod Gileadi580135c2016-10-31 20:42:19 +00001267 MetricsLogger.count(mContext, "key_back_down", 1);
Anthony Hugh96e9cc52016-07-12 15:17:24 -07001268 // Reset back key state for long press
1269 mBackKeyHandled = false;
1270
Anthony Hugh96e9cc52016-07-12 15:17:24 -07001271 if (hasLongPressOnBackBehavior()) {
1272 Message msg = mHandler.obtainMessage(MSG_BACK_LONG_PRESS);
1273 msg.setAsynchronous(true);
1274 mHandler.sendMessageDelayed(msg,
1275 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
1276 }
1277 }
1278
1279 // returns true if the key was handled and should not be passed to the user
1280 private boolean interceptBackKeyUp(KeyEvent event) {
1281 // Cache handled state
1282 boolean handled = mBackKeyHandled;
1283
Anthony Hugh96e9cc52016-07-12 15:17:24 -07001284 // Reset back long press state
1285 cancelPendingBackKeyAction();
1286
Bryce Leedb776ce2016-09-03 15:02:00 -07001287 if (mHasFeatureWatch) {
1288 TelecomManager telecomManager = getTelecommService();
1289
1290 if (telecomManager != null) {
1291 if (telecomManager.isRinging()) {
1292 // Pressing back while there's a ringing incoming
1293 // call should silence the ringer.
1294 telecomManager.silenceRinger();
1295
1296 // It should not prevent navigating away
1297 return false;
1298 } else if (
1299 (mIncallBackBehavior & Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR_HANGUP) != 0
1300 && telecomManager.isInCall()) {
1301 // Otherwise, if "Back button ends call" is enabled,
1302 // the Back button will hang up any current active call.
1303 return telecomManager.endCall();
1304 }
1305 }
1306 }
1307
Felipe Leme5f978802017-06-08 13:01:13 -07001308 if (mAutofillManagerInternal != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
1309 mHandler.sendMessage(mHandler.obtainMessage(MSG_DISPATCH_BACK_KEY_TO_AUTOFILL));
1310 }
1311
Anthony Hugh96e9cc52016-07-12 15:17:24 -07001312 return handled;
1313 }
1314
Jeff Brown13f00f02014-10-31 14:45:50 -07001315 private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
1316 // Hold a wake lock until the power key is released.
1317 if (!mPowerKeyWakeLock.isHeld()) {
1318 mPowerKeyWakeLock.acquire();
1319 }
1320
1321 // Cancel multi-press detection timeout.
1322 if (mPowerKeyPressCounter != 0) {
1323 mHandler.removeMessages(MSG_POWER_DELAYED_PRESS);
1324 }
1325
1326 // Detect user pressing the power button in panic when an application has
1327 // taken over the whole screen.
1328 boolean panic = mImmersiveModeConfirmation.onPowerKeyDown(interactive,
Adrian Roos7aaa5512016-07-12 15:27:24 -07001329 SystemClock.elapsedRealtime(), isImmersiveMode(mLastSystemUiFlags),
1330 isNavBarEmpty(mLastSystemUiFlags));
Jeff Brown13f00f02014-10-31 14:45:50 -07001331 if (panic) {
Adrian Roosddc8b272015-05-21 16:28:27 -07001332 mHandler.post(mHiddenNavPanic);
Jeff Brown13f00f02014-10-31 14:45:50 -07001333 }
1334
Adrian Roos842e7882018-03-26 17:34:06 +02001335 // Abort possibly stuck animations.
1336 mHandler.post(mWindowManagerFuncs::triggerAnimationFailsafe);
1337
Jeff Brown13f00f02014-10-31 14:45:50 -07001338 // Latch power key state to detect screenshot chord.
1339 if (interactive && !mScreenshotChordPowerKeyTriggered
1340 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
1341 mScreenshotChordPowerKeyTriggered = true;
1342 mScreenshotChordPowerKeyTime = event.getDownTime();
1343 interceptScreenshotChord();
Mike Digman55272862018-02-20 14:35:17 -08001344 interceptRingerToggleChord();
Jeff Brown13f00f02014-10-31 14:45:50 -07001345 }
1346
1347 // Stop ringing or end call if configured to do so when power is pressed.
1348 TelecomManager telecomManager = getTelecommService();
1349 boolean hungUp = false;
1350 if (telecomManager != null) {
1351 if (telecomManager.isRinging()) {
1352 // Pressing Power while there's a ringing incoming
1353 // call should silence the ringer.
1354 telecomManager.silenceRinger();
1355 } else if ((mIncallPowerBehavior
1356 & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
1357 && telecomManager.isInCall() && interactive) {
1358 // Otherwise, if "Power button ends call" is enabled,
1359 // the Power button will hang up any current active call.
1360 hungUp = telecomManager.endCall();
1361 }
1362 }
1363
Adrian Roos5941c982015-09-03 15:59:49 -07001364 GestureLauncherService gestureService = LocalServices.getService(
1365 GestureLauncherService.class);
1366 boolean gesturedServiceIntercepted = false;
1367 if (gestureService != null) {
Jorim Jaggif1cdf952016-04-05 21:41:06 -07001368 gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive,
1369 mTmpBoolean);
Selim Cinekab55ba52017-08-02 16:45:51 -07001370 if (mTmpBoolean.value && mRequestedOrGoingToSleep) {
Jorim Jaggif1cdf952016-04-05 21:41:06 -07001371 mCameraGestureTriggeredDuringGoingToSleep = true;
1372 }
Adrian Roos5941c982015-09-03 15:59:49 -07001373 }
1374
Philip Quinnc3a503d2017-07-18 23:23:41 -07001375 // Inform the StatusBar; but do not allow it to consume the event.
Philip Quinn4b5b3c62017-07-20 21:07:58 -07001376 sendSystemKeyToStatusBarAsync(event.getKeyCode());
Philip Quinnc3a503d2017-07-18 23:23:41 -07001377
Jeff Brown13f00f02014-10-31 14:45:50 -07001378 // If the power key has still not yet been handled, then detect short
1379 // press, long press, or multi press and decide what to do.
1380 mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
Phil Weaver106fe732016-11-22 18:18:39 -08001381 || mA11yShortcutChordVolumeUpKeyTriggered || gesturedServiceIntercepted;
Jeff Brown13f00f02014-10-31 14:45:50 -07001382 if (!mPowerKeyHandled) {
1383 if (interactive) {
1384 // When interactive, we're already awake.
1385 // Wait for a long press or for the button to be released to decide what to do.
1386 if (hasLongPressOnPowerBehavior()) {
Erik Wolsheimer6e029842018-02-13 11:34:00 -08001387 if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
1388 powerLongPress();
1389 } else {
1390 Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
1391 msg.setAsynchronous(true);
1392 mHandler.sendMessageDelayed(msg,
1393 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
Michael Kwan57908f02017-11-14 15:27:53 -08001394
Erik Wolsheimer6e029842018-02-13 11:34:00 -08001395 if (hasVeryLongPressOnPowerBehavior()) {
1396 Message longMsg = mHandler.obtainMessage(MSG_POWER_VERY_LONG_PRESS);
1397 longMsg.setAsynchronous(true);
1398 mHandler.sendMessageDelayed(longMsg, mVeryLongPressTimeout);
1399 }
Michael Kwan57908f02017-11-14 15:27:53 -08001400 }
Jeff Brown13f00f02014-10-31 14:45:50 -07001401 }
1402 } else {
Bryce Leed9268e32014-11-17 17:40:59 -08001403 wakeUpFromPowerKey(event.getDownTime());
Bryce Leed9268e32014-11-17 17:40:59 -08001404
Bryce Leed3b28402015-03-09 15:49:13 +00001405 if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {
Erik Wolsheimer6e029842018-02-13 11:34:00 -08001406 if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
1407 powerLongPress();
1408 } else {
1409 Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
1410 msg.setAsynchronous(true);
1411 mHandler.sendMessageDelayed(msg,
1412 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
Michael Kwan57908f02017-11-14 15:27:53 -08001413
Erik Wolsheimer6e029842018-02-13 11:34:00 -08001414 if (hasVeryLongPressOnPowerBehavior()) {
1415 Message longMsg = mHandler.obtainMessage(MSG_POWER_VERY_LONG_PRESS);
1416 longMsg.setAsynchronous(true);
1417 mHandler.sendMessageDelayed(longMsg, mVeryLongPressTimeout);
1418 }
Michael Kwan57908f02017-11-14 15:27:53 -08001419 }
1420
Bryce Leed9268e32014-11-17 17:40:59 -08001421 mBeganFromNonInteractive = true;
Bryce Leed3b28402015-03-09 15:49:13 +00001422 } else {
1423 final int maxCount = getMaxMultiPressPowerCount();
1424
1425 if (maxCount <= 1) {
1426 mPowerKeyHandled = true;
1427 } else {
1428 mBeganFromNonInteractive = true;
1429 }
Jeff Brown13f00f02014-10-31 14:45:50 -07001430 }
1431 }
Jeff Brown4d396052010-10-29 21:50:21 -07001432 }
1433 }
1434
Jeff Brown13f00f02014-10-31 14:45:50 -07001435 private void interceptPowerKeyUp(KeyEvent event, boolean interactive, boolean canceled) {
1436 final boolean handled = canceled || mPowerKeyHandled;
1437 mScreenshotChordPowerKeyTriggered = false;
1438 cancelPendingScreenshotChordAction();
1439 cancelPendingPowerKeyAction();
1440
1441 if (!handled) {
1442 // Figure out how to handle the key now that it has been released.
1443 mPowerKeyPressCounter += 1;
1444
1445 final int maxCount = getMaxMultiPressPowerCount();
1446 final long eventTime = event.getDownTime();
1447 if (mPowerKeyPressCounter < maxCount) {
1448 // This could be a multi-press. Wait a little bit longer to confirm.
1449 // Continue holding the wake lock.
1450 Message msg = mHandler.obtainMessage(MSG_POWER_DELAYED_PRESS,
1451 interactive ? 1 : 0, mPowerKeyPressCounter, eventTime);
1452 msg.setAsynchronous(true);
Alain Vongsouvanh0f63a542017-04-10 17:13:17 -07001453 mHandler.sendMessageDelayed(msg, ViewConfiguration.getMultiPressTimeout());
Jeff Brown13f00f02014-10-31 14:45:50 -07001454 return;
1455 }
1456
1457 // No other actions. Handle it immediately.
1458 powerPress(eventTime, interactive, mPowerKeyPressCounter);
Jeff Brown4d396052010-10-29 21:50:21 -07001459 }
Jeff Brown13f00f02014-10-31 14:45:50 -07001460
1461 // Done. Reset our state.
1462 finishPowerKeyPress();
1463 }
1464
1465 private void finishPowerKeyPress() {
Bryce Leed9268e32014-11-17 17:40:59 -08001466 mBeganFromNonInteractive = false;
Jeff Brown13f00f02014-10-31 14:45:50 -07001467 mPowerKeyPressCounter = 0;
1468 if (mPowerKeyWakeLock.isHeld()) {
1469 mPowerKeyWakeLock.release();
1470 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001471 }
1472
1473 private void cancelPendingPowerKeyAction() {
1474 if (!mPowerKeyHandled) {
Jeff Brown13f00f02014-10-31 14:45:50 -07001475 mPowerKeyHandled = true;
1476 mHandler.removeMessages(MSG_POWER_LONG_PRESS);
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001477 }
Michael Kwan57908f02017-11-14 15:27:53 -08001478 if (hasVeryLongPressOnPowerBehavior()) {
1479 mHandler.removeMessages(MSG_POWER_VERY_LONG_PRESS);
1480 }
Jeff Brown13f00f02014-10-31 14:45:50 -07001481 }
1482
Anthony Hugh34f09ca2016-03-04 12:03:37 -08001483 private void cancelPendingBackKeyAction() {
1484 if (!mBackKeyHandled) {
1485 mBackKeyHandled = true;
1486 mHandler.removeMessages(MSG_BACK_LONG_PRESS);
1487 }
1488 }
1489
Jeff Brown13f00f02014-10-31 14:45:50 -07001490 private void powerPress(long eventTime, boolean interactive, int count) {
1491 if (mScreenOnEarly && !mScreenOnFully) {
1492 Slog.i(TAG, "Suppressed redundant power key press while "
1493 + "already in the process of turning the screen on.");
1494 return;
Jeff Brownff204712011-10-25 21:27:54 -07001495 }
Siarhei Vishniakoubd8c29c2018-03-05 20:43:23 -08001496 Slog.d(TAG, "powerPress: eventTime=" + eventTime + " interactive=" + interactive
1497 + " count=" + count + " beganFromNonInteractive=" + mBeganFromNonInteractive +
1498 " mShortPressOnPowerBehavior=" + mShortPressOnPowerBehavior);
Jeff Brown13f00f02014-10-31 14:45:50 -07001499
1500 if (count == 2) {
1501 powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior);
1502 } else if (count == 3) {
1503 powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior);
Bryce Leed9268e32014-11-17 17:40:59 -08001504 } else if (interactive && !mBeganFromNonInteractive) {
Jeff Brown13f00f02014-10-31 14:45:50 -07001505 switch (mShortPressOnPowerBehavior) {
1506 case SHORT_PRESS_POWER_NOTHING:
1507 break;
1508 case SHORT_PRESS_POWER_GO_TO_SLEEP:
Selim Cinekab55ba52017-08-02 16:45:51 -07001509 goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
Jeff Brown13f00f02014-10-31 14:45:50 -07001510 break;
1511 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
Selim Cinekab55ba52017-08-02 16:45:51 -07001512 goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
Jeff Brown13f00f02014-10-31 14:45:50 -07001513 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
1514 break;
1515 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
Selim Cinekab55ba52017-08-02 16:45:51 -07001516 goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
Jeff Brown13f00f02014-10-31 14:45:50 -07001517 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
1518 launchHomeFromHotKey();
1519 break;
Bryce Lee01b0c5f2015-02-05 18:24:04 -08001520 case SHORT_PRESS_POWER_GO_HOME:
Andrew Zengb4045d32017-03-16 17:25:07 -07001521 shortPressPowerGoHome();
Bryce Lee01b0c5f2015-02-05 18:24:04 -08001522 break;
Yohei Yukawad6475a62017-04-17 10:35:27 -07001523 case SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME: {
Yohei Yukawaabbe1ac2017-04-18 09:43:05 -07001524 if (mDismissImeOnBackKeyPressed) {
Yohei Yukawad6475a62017-04-17 10:35:27 -07001525 if (mInputMethodManagerInternal == null) {
1526 mInputMethodManagerInternal =
1527 LocalServices.getService(InputMethodManagerInternal.class);
1528 }
1529 if (mInputMethodManagerInternal != null) {
1530 mInputMethodManagerInternal.hideCurrentInputMethod();
1531 }
1532 } else {
Andrew Zengb4045d32017-03-16 17:25:07 -07001533 shortPressPowerGoHome();
Yohei Yukawad6475a62017-04-17 10:35:27 -07001534 }
1535 break;
1536 }
Jeff Brown13f00f02014-10-31 14:45:50 -07001537 }
1538 }
1539 }
1540
Selim Cinekab55ba52017-08-02 16:45:51 -07001541 private void goToSleep(long eventTime, int reason, int flags) {
1542 mRequestedOrGoingToSleep = true;
1543 mPowerManager.goToSleep(eventTime, reason, flags);
1544 }
1545
Andrew Zengb4045d32017-03-16 17:25:07 -07001546 private void shortPressPowerGoHome() {
1547 launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/);
1548 if (isKeyguardShowingAndNotOccluded()) {
1549 // Notify keyguard so it can do any special handling for the power button since the
1550 // device will not power off and only launch home.
1551 mKeyguardDelegate.onShortPowerPressedGoHome();
1552 }
1553 }
1554
Jeff Brown13f00f02014-10-31 14:45:50 -07001555 private void powerMultiPressAction(long eventTime, boolean interactive, int behavior) {
1556 switch (behavior) {
1557 case MULTI_PRESS_POWER_NOTHING:
1558 break;
1559 case MULTI_PRESS_POWER_THEATER_MODE:
Bryce Lee3ae447e2015-06-30 12:31:41 -07001560 if (!isUserSetupComplete()) {
1561 Slog.i(TAG, "Ignoring toggling theater mode - device not setup.");
1562 break;
1563 }
1564
Jeff Brown13f00f02014-10-31 14:45:50 -07001565 if (isTheaterModeEnabled()) {
1566 Slog.i(TAG, "Toggling theater mode off.");
1567 Settings.Global.putInt(mContext.getContentResolver(),
1568 Settings.Global.THEATER_MODE_ON, 0);
1569 if (!interactive) {
1570 wakeUpFromPowerKey(eventTime);
1571 }
1572 } else {
1573 Slog.i(TAG, "Toggling theater mode on.");
1574 Settings.Global.putInt(mContext.getContentResolver(),
1575 Settings.Global.THEATER_MODE_ON, 1);
Bryce Lee55e846d2014-11-04 12:43:44 -08001576
1577 if (mGoToSleepOnButtonPressTheaterMode && interactive) {
Selim Cinekab55ba52017-08-02 16:45:51 -07001578 goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
Jeff Brown13f00f02014-10-31 14:45:50 -07001579 }
1580 }
1581 break;
1582 case MULTI_PRESS_POWER_BRIGHTNESS_BOOST:
Jeff Brown7b5be5e2014-11-12 18:45:31 -08001583 Slog.i(TAG, "Starting brightness boost.");
1584 if (!interactive) {
1585 wakeUpFromPowerKey(eventTime);
1586 }
Jeff Brown13f00f02014-10-31 14:45:50 -07001587 mPowerManager.boostScreenBrightness(eventTime);
1588 break;
1589 }
1590 }
1591
1592 private int getMaxMultiPressPowerCount() {
1593 if (mTriplePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) {
1594 return 3;
1595 }
1596 if (mDoublePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) {
1597 return 2;
1598 }
1599 return 1;
1600 }
1601
1602 private void powerLongPress() {
1603 final int behavior = getResolvedLongPressOnPowerBehavior();
1604 switch (behavior) {
1605 case LONG_PRESS_POWER_NOTHING:
1606 break;
1607 case LONG_PRESS_POWER_GLOBAL_ACTIONS:
1608 mPowerKeyHandled = true;
Phil Weaver106fe732016-11-22 18:18:39 -08001609 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
Jeff Brown13f00f02014-10-31 14:45:50 -07001610 showGlobalActionsInternal();
1611 break;
1612 case LONG_PRESS_POWER_SHUT_OFF:
1613 case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
1614 mPowerKeyHandled = true;
1615 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
1616 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
1617 mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
1618 break;
Michael Kwan57908f02017-11-14 15:27:53 -08001619 case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST:
1620 mPowerKeyHandled = true;
1621 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
1622 final boolean keyguardActive = mKeyguardDelegate == null
1623 ? false
1624 : mKeyguardDelegate.isShowing();
1625 if (!keyguardActive) {
1626 Intent intent = new Intent(Intent.ACTION_VOICE_ASSIST);
Michael Kwan7f171692018-04-04 14:00:53 -07001627 if (mAllowStartActivityForLongPressOnPowerDuringSetup) {
1628 mContext.startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
1629 } else {
1630 startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
1631 }
Michael Kwan57908f02017-11-14 15:27:53 -08001632 }
1633 break;
1634 }
1635 }
1636
1637 private void powerVeryLongPress() {
1638 switch (mVeryLongPressOnPowerBehavior) {
1639 case VERY_LONG_PRESS_POWER_NOTHING:
1640 break;
1641 case VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS:
1642 mPowerKeyHandled = true;
1643 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
1644 showGlobalActionsInternal();
1645 break;
Jeff Brown13f00f02014-10-31 14:45:50 -07001646 }
1647 }
1648
Anthony Hugh34f09ca2016-03-04 12:03:37 -08001649 private void backLongPress() {
1650 mBackKeyHandled = true;
1651
1652 switch (mLongPressOnBackBehavior) {
1653 case LONG_PRESS_BACK_NOTHING:
1654 break;
1655 case LONG_PRESS_BACK_GO_TO_VOICE_ASSIST:
Nancy Zheng0d85ee22016-09-29 09:15:56 -07001656 final boolean keyguardActive = mKeyguardDelegate == null
1657 ? false
1658 : mKeyguardDelegate.isShowing();
1659 if (!keyguardActive) {
1660 Intent intent = new Intent(Intent.ACTION_VOICE_ASSIST);
1661 startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
1662 }
Anthony Hugh34f09ca2016-03-04 12:03:37 -08001663 break;
1664 }
1665 }
1666
Phil Weaver106fe732016-11-22 18:18:39 -08001667 private void accessibilityShortcutActivated() {
1668 mAccessibilityShortcutController.performAccessibilityShortcut();
1669 }
1670
Chong Zhang9f7fb092016-05-20 17:03:08 -07001671 private void disposeInputConsumer(InputConsumer inputConsumer) {
1672 if (inputConsumer != null) {
1673 inputConsumer.dismiss();
1674 }
1675 }
1676
Siarhei Vishniakou191cf1b2017-08-17 16:17:22 -07001677 private void sleepPress() {
Nick Vaccarob593a812015-05-15 11:23:05 -07001678 if (mShortPressOnSleepBehavior == SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME) {
1679 launchHomeFromHotKey(false /* awakenDreams */, true /*respectKeyguard*/);
1680 }
1681 }
1682
1683 private void sleepRelease(long eventTime) {
Filip Gruszczynskia483a1d2015-03-17 19:06:58 +00001684 switch (mShortPressOnSleepBehavior) {
1685 case SHORT_PRESS_SLEEP_GO_TO_SLEEP:
Filip Gruszczynskia483a1d2015-03-17 19:06:58 +00001686 case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME:
Nick Vaccarob593a812015-05-15 11:23:05 -07001687 Slog.i(TAG, "sleepRelease() calling goToSleep(GO_TO_SLEEP_REASON_SLEEP_BUTTON)");
Selim Cinekab55ba52017-08-02 16:45:51 -07001688 goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0);
Filip Gruszczynskia483a1d2015-03-17 19:06:58 +00001689 break;
1690 }
1691 }
1692
Jeff Brown13f00f02014-10-31 14:45:50 -07001693 private int getResolvedLongPressOnPowerBehavior() {
1694 if (FactoryTest.isLongPressOnPowerOffEnabled()) {
1695 return LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
1696 }
1697 return mLongPressOnPowerBehavior;
1698 }
1699
1700 private boolean hasLongPressOnPowerBehavior() {
1701 return getResolvedLongPressOnPowerBehavior() != LONG_PRESS_POWER_NOTHING;
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001702 }
1703
Michael Kwan57908f02017-11-14 15:27:53 -08001704 private boolean hasVeryLongPressOnPowerBehavior() {
1705 return mVeryLongPressOnPowerBehavior != VERY_LONG_PRESS_POWER_NOTHING;
1706 }
1707
Anthony Hugh34f09ca2016-03-04 12:03:37 -08001708 private boolean hasLongPressOnBackBehavior() {
1709 return mLongPressOnBackBehavior != LONG_PRESS_BACK_NOTHING;
1710 }
1711
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001712 private void interceptScreenshotChord() {
Christopher Tatee90585f2012-03-05 18:56:25 -08001713 if (mScreenshotChordEnabled
Jeff Brown13f00f02014-10-31 14:45:50 -07001714 && mScreenshotChordVolumeDownKeyTriggered && mScreenshotChordPowerKeyTriggered
Phil Weaver106fe732016-11-22 18:18:39 -08001715 && !mA11yShortcutChordVolumeUpKeyTriggered) {
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001716 final long now = SystemClock.uptimeMillis();
Jeff Brown13f00f02014-10-31 14:45:50 -07001717 if (now <= mScreenshotChordVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS
1718 && now <= mScreenshotChordPowerKeyTime
1719 + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {
1720 mScreenshotChordVolumeDownKeyConsumed = true;
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001721 cancelPendingPowerKeyAction();
Muyuan Li6ca619f2016-03-08 13:30:42 -08001722 mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN);
Jeff Sharkey2991fa32012-12-05 18:06:43 -08001723 mHandler.postDelayed(mScreenshotRunnable, getScreenshotChordLongPressDelay());
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001724 }
1725 }
1726 }
1727
Phil Weaver106fe732016-11-22 18:18:39 -08001728 private void interceptAccessibilityShortcutChord() {
Phil Weaverce687c52017-03-15 08:51:52 -07001729 if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(isKeyguardLocked())
Phil Weaver106fe732016-11-22 18:18:39 -08001730 && mScreenshotChordVolumeDownKeyTriggered && mA11yShortcutChordVolumeUpKeyTriggered
1731 && !mScreenshotChordPowerKeyTriggered) {
1732 final long now = SystemClock.uptimeMillis();
1733 if (now <= mScreenshotChordVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS
1734 && now <= mA11yShortcutChordVolumeUpKeyTime
1735 + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {
1736 mScreenshotChordVolumeDownKeyConsumed = true;
1737 mA11yShortcutChordVolumeUpKeyConsumed = true;
1738 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT),
Eugene Susla5f19cd32017-10-19 14:00:59 -07001739 getAccessibilityShortcutTimeout());
Phil Weaver106fe732016-11-22 18:18:39 -08001740 }
1741 }
1742 }
1743
Mike Digman55272862018-02-20 14:35:17 -08001744 private void interceptRingerToggleChord() {
1745 if (mRingerToggleChord != Settings.Secure.VOLUME_HUSH_OFF
1746 && mScreenshotChordPowerKeyTriggered && mA11yShortcutChordVolumeUpKeyTriggered) {
1747 final long now = SystemClock.uptimeMillis();
1748 if (now <= mA11yShortcutChordVolumeUpKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS
1749 && now <= mScreenshotChordPowerKeyTime
1750 + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {
1751 mA11yShortcutChordVolumeUpKeyConsumed = true;
1752 cancelPendingPowerKeyAction();
1753
1754 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RINGER_TOGGLE_CHORD),
1755 getRingerToggleChordDelay());
1756 }
1757 }
1758 }
1759
Eugene Susla5f19cd32017-10-19 14:00:59 -07001760 private long getAccessibilityShortcutTimeout() {
1761 ViewConfiguration config = ViewConfiguration.get(mContext);
Phil Weaver8b78ddfd2017-11-07 16:39:19 -08001762 return Settings.Secure.getIntForUser(mContext.getContentResolver(),
1763 Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0, mCurrentUserId) == 0
1764 ? config.getAccessibilityShortcutKeyTimeout()
1765 : config.getAccessibilityShortcutKeyTimeoutAfterConfirmation();
Eugene Susla5f19cd32017-10-19 14:00:59 -07001766 }
1767
Winson Chung1cea2f32012-10-08 20:42:01 -07001768 private long getScreenshotChordLongPressDelay() {
Jim Miller5ecd8112013-01-09 18:50:26 -08001769 if (mKeyguardDelegate.isShowing()) {
Winson Chung1cea2f32012-10-08 20:42:01 -07001770 // Double the time it takes to take a screenshot from the keyguard
1771 return (long) (KEYGUARD_SCREENSHOT_CHORD_DELAY_MULTIPLIER *
Justin Kohfeabd2c2014-05-02 10:02:44 -07001772 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
Winson Chung1cea2f32012-10-08 20:42:01 -07001773 }
Justin Kohfeabd2c2014-05-02 10:02:44 -07001774 return ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout();
Winson Chung1cea2f32012-10-08 20:42:01 -07001775 }
1776
Mike Digman55272862018-02-20 14:35:17 -08001777 private long getRingerToggleChordDelay() {
1778 // Always timeout like a tap
1779 return ViewConfiguration.getTapTimeout();
1780 }
1781
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001782 private void cancelPendingScreenshotChordAction() {
Jeff Sharkey2991fa32012-12-05 18:06:43 -08001783 mHandler.removeCallbacks(mScreenshotRunnable);
Jeff Brown4d396052010-10-29 21:50:21 -07001784 }
1785
Phil Weaver106fe732016-11-22 18:18:39 -08001786 private void cancelPendingAccessibilityShortcutAction() {
1787 mHandler.removeMessages(MSG_ACCESSIBILITY_SHORTCUT);
1788 }
1789
Mike Digman55272862018-02-20 14:35:17 -08001790 private void cancelPendingRingerToggleChordAction() {
1791 mHandler.removeMessages(MSG_RINGER_TOGGLE_CHORD);
1792 }
1793
Jeff Brown13f00f02014-10-31 14:45:50 -07001794 private final Runnable mEndCallLongPress = new Runnable() {
Craig Mautnerf1b67412012-09-19 13:18:29 -07001795 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001796 public void run() {
Jeff Brown13f00f02014-10-31 14:45:50 -07001797 mEndCallKeyHandled = true;
Phil Weaver106fe732016-11-22 18:18:39 -08001798 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
Jeff Brown13f00f02014-10-31 14:45:50 -07001799 showGlobalActionsInternal();
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001800 }
1801 };
1802
Muyuan Li6ca619f2016-03-08 13:30:42 -08001803 private class ScreenshotRunnable implements Runnable {
1804 private int mScreenshotType = TAKE_SCREENSHOT_FULLSCREEN;
1805
1806 public void setScreenshotType(int screenshotType) {
1807 mScreenshotType = screenshotType;
1808 }
1809
Craig Mautner0bf6ec92012-12-18 08:33:27 -08001810 @Override
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001811 public void run() {
Alison Cichowlasa2cd19e2017-12-06 10:51:21 -05001812 mScreenshotHelper.takeScreenshot(mScreenshotType,
1813 mStatusBar != null && mStatusBar.isVisibleLw(),
1814 mNavigationBar != null && mNavigationBar.isVisibleLw(), mHandler);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001815 }
Muyuan Li6ca619f2016-03-08 13:30:42 -08001816 }
1817
1818 private final ScreenshotRunnable mScreenshotRunnable = new ScreenshotRunnable();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001819
Alan Viverettee34560b22014-07-10 14:50:06 -07001820 @Override
1821 public void showGlobalActions() {
1822 mHandler.removeMessages(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS);
1823 mHandler.sendEmptyMessage(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS);
1824 }
1825
1826 void showGlobalActionsInternal() {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001827 if (mGlobalActions == null) {
Jeff Brown7304c342012-05-11 18:42:42 -07001828 mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001829 }
Jim Millerab954542014-10-10 18:21:49 -07001830 final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001831 mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
1832 if (keyguardShowing) {
1833 // since it took two seconds of long press to bring this up,
1834 // poke the wake lock so they have some time to see the dialog.
Jim Miller25190572013-02-28 17:36:24 -08001835 mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001836 }
1837 }
1838
1839 boolean isDeviceProvisioned() {
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001840 return Settings.Global.getInt(
1841 mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001842 }
1843
Maurice Lam99c6e072014-04-28 18:24:28 -07001844 boolean isUserSetupComplete() {
Sujith Ramakrishnan0390fff2017-06-08 18:18:12 -07001845 boolean isSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(),
Maurice Lam99c6e072014-04-28 18:24:28 -07001846 Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
Sujith Ramakrishnan0390fff2017-06-08 18:18:12 -07001847 if (mHasFeatureLeanback) {
1848 isSetupComplete &= isTvUserSetupComplete();
1849 }
1850 return isSetupComplete;
1851 }
1852
1853 private boolean isTvUserSetupComplete() {
1854 return Settings.Secure.getIntForUser(mContext.getContentResolver(),
1855 Settings.Secure.TV_USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
Maurice Lam99c6e072014-04-28 18:24:28 -07001856 }
1857
Jeff Brown13f00f02014-10-31 14:45:50 -07001858 private void handleShortPressOnHome() {
Jinsuk Kime601b712015-07-07 08:01:02 +09001859 // Turn on the connected TV and switch HDMI input if we're a HDMI playback device.
Andrii Kulianeb4a7942016-12-21 12:18:05 -08001860 final HdmiControl hdmiControl = getHdmiControl();
1861 if (hdmiControl != null) {
1862 hdmiControl.turnOnTv();
1863 }
Jinsuk Kime601b712015-07-07 08:01:02 +09001864
Jeff Brown13f00f02014-10-31 14:45:50 -07001865 // If there's a dream running then use home to escape the dream
1866 // but don't actually go home.
1867 if (mDreamManagerInternal != null && mDreamManagerInternal.isDreaming()) {
1868 mDreamManagerInternal.stopDream(false /*immediate*/);
1869 return;
1870 }
1871
1872 // Go home!
1873 launchHomeFromHotKey();
1874 }
1875
Jinsuk Kime601b712015-07-07 08:01:02 +09001876 /**
1877 * Creates an accessor to HDMI control service that performs the operation of
1878 * turning on TV (optional) and switching input to us. If HDMI control service
1879 * is not available or we're not a HDMI playback device, the operation is no-op.
Andrii Kulianeb4a7942016-12-21 12:18:05 -08001880 * @return {@link HdmiControl} instance if available, null otherwise.
Jinsuk Kime601b712015-07-07 08:01:02 +09001881 */
1882 private HdmiControl getHdmiControl() {
1883 if (null == mHdmiControl) {
Andrii Kulianeb4a7942016-12-21 12:18:05 -08001884 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) {
1885 return null;
1886 }
Jinsuk Kime601b712015-07-07 08:01:02 +09001887 HdmiControlManager manager = (HdmiControlManager) mContext.getSystemService(
1888 Context.HDMI_CONTROL_SERVICE);
1889 HdmiPlaybackClient client = null;
1890 if (manager != null) {
1891 client = manager.getPlaybackClient();
1892 }
1893 mHdmiControl = new HdmiControl(client);
1894 }
1895 return mHdmiControl;
1896 }
1897
1898 private static class HdmiControl {
1899 private final HdmiPlaybackClient mClient;
1900
1901 private HdmiControl(HdmiPlaybackClient client) {
1902 mClient = client;
1903 }
1904
1905 public void turnOnTv() {
1906 if (mClient == null) {
1907 return;
1908 }
1909 mClient.oneTouchPlay(new OneTouchPlayCallback() {
1910 @Override
1911 public void onComplete(int result) {
1912 if (result != HdmiControlManager.RESULT_SUCCESS) {
1913 Log.w(TAG, "One touch play failed: " + result);
1914 }
1915 }
1916 });
1917 }
1918 }
1919
Jaewan Kim76b7d0d2016-02-12 19:01:02 +09001920 private void handleLongPressOnHome(int deviceId) {
Jaewan Kim52632e22016-01-14 18:01:52 +09001921 if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_NOTHING) {
1922 return;
1923 }
1924 mHomeConsumed = true;
1925 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
Jaewan Kim52632e22016-01-14 18:01:52 +09001926 switch (mLongPressOnHomeBehavior) {
Sid Soundararajanff662fa2017-03-15 16:24:24 -07001927 case LONG_PRESS_HOME_ALL_APPS:
1928 launchAllAppsAction();
Jaewan Kim52632e22016-01-14 18:01:52 +09001929 break;
1930 case LONG_PRESS_HOME_ASSIST:
Tim Kilbourn0e5f1102015-06-05 16:18:09 -07001931 launchAssistAction(null, deviceId);
Jaewan Kim52632e22016-01-14 18:01:52 +09001932 break;
Jaewan Kim52632e22016-01-14 18:01:52 +09001933 default:
Jaewan Kim76b7d0d2016-02-12 19:01:02 +09001934 Log.w(TAG, "Undefined home long press behavior: " + mLongPressOnHomeBehavior);
Jaewan Kim52632e22016-01-14 18:01:52 +09001935 break;
Jim Millere6ad1a82010-08-20 19:25:39 -07001936 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001937 }
Patrick Dubroyece94522011-02-23 18:35:01 -08001938
Sid Soundararajanff662fa2017-03-15 16:24:24 -07001939 private void launchAllAppsAction() {
1940 Intent intent = new Intent(Intent.ACTION_ALL_APPS);
Sujith Ramakrishnanf8942c02017-07-18 18:35:14 -07001941 if (mHasFeatureLeanback) {
1942 final PackageManager pm = mContext.getPackageManager();
1943 Intent intentLauncher = new Intent(Intent.ACTION_MAIN);
1944 intentLauncher.addCategory(Intent.CATEGORY_HOME);
1945 ResolveInfo resolveInfo = pm.resolveActivityAsUser(intentLauncher,
1946 PackageManager.MATCH_SYSTEM_ONLY,
1947 mCurrentUserId);
1948 if (resolveInfo != null) {
1949 intent.setPackage(resolveInfo.activityInfo.packageName);
1950 }
1951 }
Sid Soundararajanff662fa2017-03-15 16:24:24 -07001952 startActivityAsUser(intent, UserHandle.CURRENT);
1953 }
1954
Jeff Browncaca8812013-05-09 13:34:33 -07001955 private void handleDoubleTapOnHome() {
1956 if (mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) {
1957 mHomeConsumed = true;
1958 toggleRecentApps();
1959 }
1960 }
1961
Winson Chungac52f282017-03-30 14:44:52 -07001962 private void showPictureInPictureMenu(KeyEvent event) {
1963 if (DEBUG_INPUT) Log.d(TAG, "showPictureInPictureMenu event=" + event);
1964 mHandler.removeMessages(MSG_SHOW_PICTURE_IN_PICTURE_MENU);
1965 Message msg = mHandler.obtainMessage(MSG_SHOW_PICTURE_IN_PICTURE_MENU);
Jaewan Kimc552b042016-01-18 16:08:45 +09001966 msg.setAsynchronous(true);
1967 msg.sendToTarget();
1968 }
1969
Winson Chungac52f282017-03-30 14:44:52 -07001970 private void showPictureInPictureMenuInternal() {
Jaewan Kimf0fd2182016-04-20 21:17:58 +09001971 StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
1972 if (statusbar != null) {
Winson Chungac52f282017-03-30 14:44:52 -07001973 statusbar.showPictureInPictureMenu();
Jaewan Kimc552b042016-01-18 16:08:45 +09001974 }
Jaewan Kim52632e22016-01-14 18:01:52 +09001975 }
1976
Jeff Browncaca8812013-05-09 13:34:33 -07001977 private final Runnable mHomeDoubleTapTimeoutRunnable = new Runnable() {
1978 @Override
1979 public void run() {
1980 if (mHomeDoubleTapPending) {
1981 mHomeDoubleTapPending = false;
Jeff Brown13f00f02014-10-31 14:45:50 -07001982 handleShortPressOnHome();
Jeff Browncaca8812013-05-09 13:34:33 -07001983 }
1984 }
1985 };
1986
Mark Renoufc1256912015-03-11 14:38:23 -04001987 private boolean isRoundWindow() {
Adam Powell01f280d2015-05-18 16:07:42 -07001988 return mContext.getResources().getConfiguration().isScreenRound();
Mark Renoufc1256912015-03-11 14:38:23 -04001989 }
1990
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001991 /** {@inheritDoc} */
Craig Mautner0bf6ec92012-12-18 08:33:27 -08001992 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001993 public void init(Context context, IWindowManager windowManager,
Jeff Brown96307042012-07-27 15:51:34 -07001994 WindowManagerFuncs windowManagerFuncs) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001995 mContext = context;
1996 mWindowManager = windowManager;
Dianne Hackborndf89e652011-10-06 22:35:11 -07001997 mWindowManagerFuncs = windowManagerFuncs;
Craig Mautner8a0da012014-05-31 15:13:37 -07001998 mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
Jeff Brown061ea992015-04-17 19:55:47 -07001999 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
Andrii Kulian112d0562016-03-08 10:44:22 -08002000 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Jose Lima9546b202014-07-02 17:21:51 -07002001 mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
Michael Wrighta4d22d72015-09-16 23:19:26 +01002002 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
Billy Laucbe540f2015-06-25 01:51:44 +01002003 mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
Wale Ogunwale6b15ea52016-04-04 07:28:27 -07002004 mHasFeatureWatch = mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH);
Dmitri Plotnikov82e6dfc2017-02-24 18:10:54 -08002005 mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK);
Phil Weaver106fe732016-11-22 18:18:39 -08002006 mAccessibilityShortcutController =
Phil Weaverce687c52017-03-15 08:51:52 -07002007 new AccessibilityShortcutController(mContext, new Handler(), mCurrentUserId);
Mark Renoufc1256912015-03-11 14:38:23 -04002008 // Init display burn-in protection
2009 boolean burnInProtectionEnabled = context.getResources().getBoolean(
2010 com.android.internal.R.bool.config_enableBurnInProtection);
2011 // Allow a system property to override this. Used by developer settings.
2012 boolean burnInProtectionDevMode =
2013 SystemProperties.getBoolean("persist.debug.force_burn_in", false);
2014 if (burnInProtectionEnabled || burnInProtectionDevMode) {
2015 final int minHorizontal;
2016 final int maxHorizontal;
2017 final int minVertical;
2018 final int maxVertical;
2019 final int maxRadius;
2020 if (burnInProtectionDevMode) {
2021 minHorizontal = -8;
2022 maxHorizontal = 8;
2023 minVertical = -8;
2024 maxVertical = -4;
2025 maxRadius = (isRoundWindow()) ? 6 : -1;
2026 } else {
2027 Resources resources = context.getResources();
2028 minHorizontal = resources.getInteger(
2029 com.android.internal.R.integer.config_burnInProtectionMinHorizontalOffset);
2030 maxHorizontal = resources.getInteger(
2031 com.android.internal.R.integer.config_burnInProtectionMaxHorizontalOffset);
2032 minVertical = resources.getInteger(
2033 com.android.internal.R.integer.config_burnInProtectionMinVerticalOffset);
2034 maxVertical = resources.getInteger(
2035 com.android.internal.R.integer.config_burnInProtectionMaxVerticalOffset);
2036 maxRadius = resources.getInteger(
2037 com.android.internal.R.integer.config_burnInProtectionMaxRadius);
2038 }
2039 mBurnInProtectionHelper = new BurnInProtectionHelper(
2040 context, minHorizontal, maxHorizontal, minVertical, maxVertical, maxRadius);
Filip Gruszczynskicfb31852015-02-25 21:47:12 +00002041 }
Craig Mautner8a0da012014-05-31 15:13:37 -07002042
Jeff Brown70825162012-03-28 17:27:48 -07002043 mHandler = new PolicyHandler();
Jeff Browna20dda42014-05-27 20:57:24 -07002044 mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
Craig Mautnereee29c42013-01-17 14:44:34 -08002045 mOrientationListener = new MyOrientationListener(mContext, mHandler);
Jeff Brownc0347aa2011-09-23 17:26:09 -07002046 try {
Andrii Kulian8ee72852017-03-10 10:36:45 -08002047 mOrientationListener.setCurrentRotation(windowManager.getDefaultDisplayRotation());
Jeff Brownc0347aa2011-09-23 17:26:09 -07002048 } catch (RemoteException ex) { }
Christopher Tate5e08af02012-09-21 17:17:22 -07002049 mSettingsObserver = new SettingsObserver(mHandler);
2050 mSettingsObserver.observe();
Svetoslav683914b2015-01-15 14:22:26 -08002051 mShortcutManager = new ShortcutManager(context);
Daniel Sandler6396c722013-04-16 20:19:09 -04002052 mUiMode = context.getResources().getInteger(
2053 com.android.internal.R.integer.config_defaultUiModeType);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002054 mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
2055 mHomeIntent.addCategory(Intent.CATEGORY_HOME);
2056 mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
2057 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
keunyounga7710492015-09-23 11:33:58 -07002058 mEnableCarDockHomeCapture = context.getResources().getBoolean(
2059 com.android.internal.R.bool.config_enableCarDockHomeLaunch);
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002060 mCarDockIntent = new Intent(Intent.ACTION_MAIN, null);
2061 mCarDockIntent.addCategory(Intent.CATEGORY_CAR_DOCK);
2062 mCarDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
2063 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
2064 mDeskDockIntent = new Intent(Intent.ACTION_MAIN, null);
2065 mDeskDockIntent.addCategory(Intent.CATEGORY_DESK_DOCK);
2066 mDeskDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
2067 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
Zak Cohendb6ca492017-01-26 14:09:00 -08002068 mVrHeadsetHomeIntent = new Intent(Intent.ACTION_MAIN, null);
2069 mVrHeadsetHomeIntent.addCategory(Intent.CATEGORY_VR_HOME);
2070 mVrHeadsetHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
2071 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
Jim Millere6ad1a82010-08-20 19:25:39 -07002072
Jeff Brown96307042012-07-27 15:51:34 -07002073 mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
2074 mBroadcastWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002075 "PhoneWindowManager.mBroadcastWakeLock");
Jeff Brown13f00f02014-10-31 14:45:50 -07002076 mPowerKeyWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
2077 "PhoneWindowManager.mPowerKeyWakeLock");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002078 mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable"));
Jeff Brownbcdfc622014-03-06 19:13:04 -08002079 mSupportAutoRotation = mContext.getResources().getBoolean(
2080 com.android.internal.R.bool.config_supportAutoRotation);
Dianne Hackborn2862fff2009-09-15 22:56:29 -07002081 mLidOpenRotation = readRotation(
Mike Lockwood2d1efbd2009-09-16 12:15:53 -04002082 com.android.internal.R.integer.config_lidOpenRotation);
2083 mCarDockRotation = readRotation(
2084 com.android.internal.R.integer.config_carDockRotation);
2085 mDeskDockRotation = readRotation(
2086 com.android.internal.R.integer.config_deskDockRotation);
Jeff Brownc82c89ed2013-04-17 17:18:15 -07002087 mUndockedHdmiRotation = readRotation(
2088 com.android.internal.R.integer.config_undockedHdmiRotation);
Mike Lockwoode9867d22009-09-20 01:59:02 -04002089 mCarDockEnablesAccelerometer = mContext.getResources().getBoolean(
2090 com.android.internal.R.bool.config_carDockEnablesAccelerometer);
2091 mDeskDockEnablesAccelerometer = mContext.getResources().getBoolean(
2092 com.android.internal.R.bool.config_deskDockEnablesAccelerometer);
Dianne Hackborn2862fff2009-09-15 22:56:29 -07002093 mLidKeyboardAccessibility = mContext.getResources().getInteger(
2094 com.android.internal.R.integer.config_lidKeyboardAccessibility);
2095 mLidNavigationAccessibility = mContext.getResources().getInteger(
2096 com.android.internal.R.integer.config_lidNavigationAccessibility);
Edward Savage-Jones7def60d2015-11-13 13:27:03 +01002097 mLidControlsScreenLock = mContext.getResources().getBoolean(
2098 com.android.internal.R.bool.config_lidControlsScreenLock);
Jeff Brownc458ce92012-04-30 14:58:40 -07002099 mLidControlsSleep = mContext.getResources().getBoolean(
2100 com.android.internal.R.bool.config_lidControlsSleep);
Daniel Sandlerdd73ee42013-10-11 22:19:59 -04002101 mTranslucentDecorEnabled = mContext.getResources().getBoolean(
2102 com.android.internal.R.bool.config_enableTranslucentDecor);
Bryce Lee584a4452014-10-21 15:55:55 -07002103
2104 mAllowTheaterModeWakeFromKey = mContext.getResources().getBoolean(
2105 com.android.internal.R.bool.config_allowTheaterModeWakeFromKey);
2106 mAllowTheaterModeWakeFromPowerKey = mAllowTheaterModeWakeFromKey
2107 || mContext.getResources().getBoolean(
2108 com.android.internal.R.bool.config_allowTheaterModeWakeFromPowerKey);
2109 mAllowTheaterModeWakeFromMotion = mContext.getResources().getBoolean(
2110 com.android.internal.R.bool.config_allowTheaterModeWakeFromMotion);
Bryce Lee812d7022014-11-10 13:33:28 -08002111 mAllowTheaterModeWakeFromMotionWhenNotDreaming = mContext.getResources().getBoolean(
2112 com.android.internal.R.bool.config_allowTheaterModeWakeFromMotionWhenNotDreaming);
Bryce Lee584a4452014-10-21 15:55:55 -07002113 mAllowTheaterModeWakeFromCameraLens = mContext.getResources().getBoolean(
2114 com.android.internal.R.bool.config_allowTheaterModeWakeFromCameraLens);
2115 mAllowTheaterModeWakeFromLidSwitch = mContext.getResources().getBoolean(
2116 com.android.internal.R.bool.config_allowTheaterModeWakeFromLidSwitch);
2117 mAllowTheaterModeWakeFromWakeGesture = mContext.getResources().getBoolean(
2118 com.android.internal.R.bool.config_allowTheaterModeWakeFromGesture);
2119
Bryce Lee55e846d2014-11-04 12:43:44 -08002120 mGoToSleepOnButtonPressTheaterMode = mContext.getResources().getBoolean(
2121 com.android.internal.R.bool.config_goToSleepOnButtonPressTheaterMode);
2122
Bryce Leed3b28402015-03-09 15:49:13 +00002123 mSupportLongPressPowerWhenNonInteractive = mContext.getResources().getBoolean(
2124 com.android.internal.R.bool.config_supportLongPressPowerWhenNonInteractive);
2125
Anthony Hugh34f09ca2016-03-04 12:03:37 -08002126 mLongPressOnBackBehavior = mContext.getResources().getInteger(
2127 com.android.internal.R.integer.config_longPressOnBackBehavior);
2128
Jeff Brown13f00f02014-10-31 14:45:50 -07002129 mShortPressOnPowerBehavior = mContext.getResources().getInteger(
2130 com.android.internal.R.integer.config_shortPressOnPowerBehavior);
2131 mLongPressOnPowerBehavior = mContext.getResources().getInteger(
2132 com.android.internal.R.integer.config_longPressOnPowerBehavior);
Michael Kwan57908f02017-11-14 15:27:53 -08002133 mVeryLongPressOnPowerBehavior = mContext.getResources().getInteger(
2134 com.android.internal.R.integer.config_veryLongPressOnPowerBehavior);
Jeff Brown13f00f02014-10-31 14:45:50 -07002135 mDoublePressOnPowerBehavior = mContext.getResources().getInteger(
2136 com.android.internal.R.integer.config_doublePressOnPowerBehavior);
2137 mTriplePressOnPowerBehavior = mContext.getResources().getInteger(
2138 com.android.internal.R.integer.config_triplePressOnPowerBehavior);
Filip Gruszczynskia483a1d2015-03-17 19:06:58 +00002139 mShortPressOnSleepBehavior = mContext.getResources().getInteger(
2140 com.android.internal.R.integer.config_shortPressOnSleepBehavior);
Michael Kwan57908f02017-11-14 15:27:53 -08002141 mVeryLongPressTimeout = mContext.getResources().getInteger(
2142 com.android.internal.R.integer.config_veryLongPressTimeout);
Michael Kwan7f171692018-04-04 14:00:53 -07002143 mAllowStartActivityForLongPressOnPowerDuringSetup = mContext.getResources().getBoolean(
2144 com.android.internal.R.bool.config_allowStartActivityForLongPressOnPowerInSetup);
Jeff Brown13f00f02014-10-31 14:45:50 -07002145
John Spurlock61560172015-02-06 19:46:04 -05002146 mUseTvRouting = AudioSystem.getPlatformType(mContext) == AudioSystem.PLATFORM_TELEVISION;
RoboErik001c59c2015-01-26 15:53:51 -08002147
Karthik Ravi Shankar86ecf342017-04-28 15:35:58 -07002148 mHandleVolumeKeysInWM = mContext.getResources().getBoolean(
2149 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager);
2150
Jeff Brownf71343d2013-05-31 17:59:11 -07002151 readConfigurationDependentBehaviors();
Jeff Browncaca8812013-05-09 13:34:33 -07002152
Svetoslav8e3feb12014-02-24 13:46:47 -08002153 mAccessibilityManager = (AccessibilityManager) context.getSystemService(
2154 Context.ACCESSIBILITY_SERVICE);
2155
Mike Lockwood1753f7f2009-08-24 14:49:07 -07002156 // register for dock events
Dianne Hackborn78968392010-03-04 20:47:56 -08002157 IntentFilter filter = new IntentFilter();
2158 filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
2159 filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE);
2160 filter.addAction(UiModeManager.ACTION_ENTER_DESK_MODE);
2161 filter.addAction(UiModeManager.ACTION_EXIT_DESK_MODE);
Dianne Hackborn867ab6472010-04-29 13:28:56 -07002162 filter.addAction(Intent.ACTION_DOCK_EVENT);
2163 Intent intent = context.registerReceiver(mDockReceiver, filter);
2164 if (intent != null) {
2165 // Retrieve current sticky dock event broadcast.
2166 mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
2167 Intent.EXTRA_DOCK_STATE_UNDOCKED);
2168 }
Daniel Sandler7e37df52011-11-16 22:08:23 -08002169
Jeff Brown6aaf2952012-10-05 16:01:08 -07002170 // register for dream-related broadcasts
2171 filter = new IntentFilter();
2172 filter.addAction(Intent.ACTION_DREAMING_STARTED);
2173 filter.addAction(Intent.ACTION_DREAMING_STOPPED);
2174 context.registerReceiver(mDreamReceiver, filter);
2175
Christopher Tate5e08af02012-09-21 17:17:22 -07002176 // register for multiuser-relevant broadcasts
2177 filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
2178 context.registerReceiver(mMultiuserReceiver, filter);
2179
John Spurlock57306e62013-04-22 09:48:49 -04002180 // monitor for system gestures
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00002181 // TODO(multi-display): Needs to be display specific.
Craig Mautner037aa8d2013-06-07 10:35:44 -07002182 mSystemGestures = new SystemGesturesPointerEventListener(context,
2183 new SystemGesturesPointerEventListener.Callbacks() {
John Spurlock57306e62013-04-22 09:48:49 -04002184 @Override
2185 public void onSwipeFromTop() {
John Spurlock04db1762013-05-13 12:46:41 -04002186 if (mStatusBar != null) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002187 requestTransientBars(mStatusBar);
John Spurlock04db1762013-05-13 12:46:41 -04002188 }
John Spurlockad3e6cb2013-04-30 08:47:43 -04002189 }
2190 @Override
2191 public void onSwipeFromBottom() {
Adrian Roos85d202b2016-06-02 16:27:47 -07002192 if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002193 requestTransientBars(mNavigationBar);
John Spurlockad3e6cb2013-04-30 08:47:43 -04002194 }
2195 }
2196 @Override
2197 public void onSwipeFromRight() {
Adrian Roos85d202b2016-06-02 16:27:47 -07002198 if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) {
2199 requestTransientBars(mNavigationBar);
2200 }
2201 }
2202 @Override
2203 public void onSwipeFromLeft() {
2204 if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002205 requestTransientBars(mNavigationBar);
John Spurlockad3e6cb2013-04-30 08:47:43 -04002206 }
2207 }
2208 @Override
Michael Wrighta4d22d72015-09-16 23:19:26 +01002209 public void onFling(int duration) {
2210 if (mPowerManagerInternal != null) {
2211 mPowerManagerInternal.powerHint(
Ruchi Kandoi0d434042016-10-03 09:12:02 -07002212 PowerHint.INTERACTION, duration);
Michael Wrighta4d22d72015-09-16 23:19:26 +01002213 }
2214 }
2215 @Override
John Spurlockad3e6cb2013-04-30 08:47:43 -04002216 public void onDebug() {
John Spurlockd67ec252013-09-05 11:31:54 -04002217 // no-op
John Spurlockad3e6cb2013-04-30 08:47:43 -04002218 }
Adrian Roos3595be42015-03-05 16:31:15 +01002219 @Override
2220 public void onDown() {
2221 mOrientationListener.onTouchStart();
2222 }
2223 @Override
2224 public void onUpOrCancel() {
2225 mOrientationListener.onTouchEnd();
2226 }
Jun Mukaid2e7e352015-07-22 17:14:02 -07002227 @Override
2228 public void onMouseHoverAtTop() {
2229 mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
2230 Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
2231 msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS;
2232 mHandler.sendMessageDelayed(msg, 500);
2233 }
2234 @Override
2235 public void onMouseHoverAtBottom() {
2236 mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
2237 Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
2238 msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION;
2239 mHandler.sendMessageDelayed(msg, 500);
2240 }
2241 @Override
2242 public void onMouseLeaveFromEdge() {
2243 mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
2244 }
John Spurlockad3e6cb2013-04-30 08:47:43 -04002245 });
John Spurlockf1a36642013-10-12 17:50:42 -04002246 mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext);
Craig Mautner037aa8d2013-06-07 10:35:44 -07002247 mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);
John Spurlock32beb2c2013-03-11 10:16:47 -04002248
Jeff Brownc2346132012-04-13 01:55:38 -07002249 mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
Dianne Hackbornb1a79802009-09-29 15:18:31 -07002250 mLongPressVibePattern = getLongIntArray(mContext.getResources(),
2251 com.android.internal.R.array.config_longPressVibePattern);
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -07002252 mCalendarDateVibePattern = getLongIntArray(mContext.getResources(),
2253 com.android.internal.R.array.config_calendarDateVibePattern);
Dianne Hackbornb1a79802009-09-29 15:18:31 -07002254 mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
2255 com.android.internal.R.array.config_safeModeEnabledVibePattern);
Daniel Sandler40427442010-07-16 11:44:52 -04002256
Christopher Tatee90585f2012-03-05 18:56:25 -08002257 mScreenshotChordEnabled = mContext.getResources().getBoolean(
2258 com.android.internal.R.bool.config_enableScreenshotChord);
2259
Justin Kohd378ad72013-04-01 12:18:26 -07002260 mGlobalKeyManager = new GlobalKeyManager(mContext);
2261
Joe Onoratoea495d42011-04-06 11:41:11 -07002262 // Controls rotation and the like.
2263 initializeHdmiState();
Dianne Hackborn40011092011-09-22 13:37:48 -07002264
2265 // Match current screen state.
Craig Mautnera631d492014-08-05 15:16:01 -07002266 if (!mPowerManager.isInteractive()) {
Jeff Brown416c49c2015-05-26 19:50:18 -07002267 startedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
2268 finishedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
Dianne Hackborn40011092011-09-22 13:37:48 -07002269 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01002270
2271 mWindowManagerInternal.registerAppTransitionListener(
2272 mStatusBarController.getAppTransitionListener());
Jorim Jaggife762342016-10-13 14:33:27 +02002273 mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() {
2274 @Override
2275 public int onAppTransitionStartingLocked(int transit, IBinder openToken,
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002276 IBinder closeToken, long duration, long statusBarAnimationStartTime,
2277 long statusBarAnimationDuration) {
2278 return handleStartTransitionForKeyguardLw(transit, duration);
Jorim Jaggife762342016-10-13 14:33:27 +02002279 }
2280
2281 @Override
2282 public void onAppTransitionCancelledLocked(int transit) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002283 handleStartTransitionForKeyguardLw(transit, 0 /* duration */);
Jorim Jaggife762342016-10-13 14:33:27 +02002284 }
2285 });
Keun-young Park4136d2d2017-05-08 14:51:59 -07002286 mKeyguardDelegate = new KeyguardServiceDelegate(mContext,
2287 new StateCallback() {
2288 @Override
2289 public void onTrustedChanged() {
2290 mWindowManagerFuncs.notifyKeyguardTrustedChanged();
2291 }
2292 });
Alison Cichowlasa2cd19e2017-12-06 10:51:21 -05002293 mScreenshotHelper = new ScreenshotHelper(mContext);
Mike Lockwood1753f7f2009-08-24 14:49:07 -07002294 }
2295
Jeff Brownf71343d2013-05-31 17:59:11 -07002296 /**
2297 * Read values from config.xml that may be overridden depending on
2298 * the configuration of the device.
2299 * eg. Disable long press on home goes to recents on sw600dp.
2300 */
2301 private void readConfigurationDependentBehaviors() {
Jaewan Kimc552b042016-01-18 16:08:45 +09002302 final Resources res = mContext.getResources();
2303
2304 mLongPressOnHomeBehavior = res.getInteger(
Jeff Brownf71343d2013-05-31 17:59:11 -07002305 com.android.internal.R.integer.config_longPressOnHomeBehavior);
2306 if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING ||
Jaewan Kim52632e22016-01-14 18:01:52 +09002307 mLongPressOnHomeBehavior > LAST_LONG_PRESS_HOME_BEHAVIOR) {
Jeff Brownf71343d2013-05-31 17:59:11 -07002308 mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
2309 }
2310
Jaewan Kimc552b042016-01-18 16:08:45 +09002311 mDoubleTapOnHomeBehavior = res.getInteger(
Jeff Brownf71343d2013-05-31 17:59:11 -07002312 com.android.internal.R.integer.config_doubleTapOnHomeBehavior);
2313 if (mDoubleTapOnHomeBehavior < DOUBLE_TAP_HOME_NOTHING ||
2314 mDoubleTapOnHomeBehavior > DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) {
2315 mDoubleTapOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
2316 }
Jaewan Kim49117872016-01-19 17:24:08 +09002317
Michael Wright19859762017-09-18 20:57:58 +01002318 mShortPressOnWindowBehavior = SHORT_PRESS_WINDOW_NOTHING;
Jaewan Kim49117872016-01-19 17:24:08 +09002319 if (mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {
Michael Wright19859762017-09-18 20:57:58 +01002320 mShortPressOnWindowBehavior = SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE;
Jaewan Kim49117872016-01-19 17:24:08 +09002321 }
Yorke Lee2e4b7322016-03-02 17:33:06 -08002322
Yorke Lee9b2ffb32016-03-07 20:42:01 -08002323 mNavBarOpacityMode = res.getInteger(
2324 com.android.internal.R.integer.config_navBarOpacityMode);
Jeff Brownf71343d2013-05-31 17:59:11 -07002325 }
2326
Craig Mautner0bf6ec92012-12-18 08:33:27 -08002327 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07002328 public void setInitialDisplaySize(Display display, int width, int height, int density) {
Jeff Brownef981a42013-08-07 14:13:37 -07002329 // This method might be called before the policy has been fully initialized
2330 // or for other displays we don't care about.
Andrii Kulian3a507b52016-09-19 18:14:12 -07002331 // TODO(multi-display): Define policy for secondary displays.
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02002332 if (mContext == null || display.getDisplayId() != DEFAULT_DISPLAY) {
Jeff Brownef981a42013-08-07 14:13:37 -07002333 return;
Dianne Hackbornc652de82013-02-15 16:32:56 -08002334 }
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002335 mDisplay = display;
2336
Craig Mautner46ac6fa2013-08-01 10:06:34 -07002337 final Resources res = mContext.getResources();
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002338 int shortSize, longSize;
Dianne Hackborn9d132642011-04-21 17:26:39 -07002339 if (width > height) {
Dianne Hackborn81e56d52011-05-26 00:55:58 -07002340 shortSize = height;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002341 longSize = width;
Dianne Hackborn9d132642011-04-21 17:26:39 -07002342 mLandscapeRotation = Surface.ROTATION_0;
2343 mSeascapeRotation = Surface.ROTATION_180;
Craig Mautner46ac6fa2013-08-01 10:06:34 -07002344 if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
Dianne Hackborn9d132642011-04-21 17:26:39 -07002345 mPortraitRotation = Surface.ROTATION_90;
2346 mUpsideDownRotation = Surface.ROTATION_270;
2347 } else {
2348 mPortraitRotation = Surface.ROTATION_270;
2349 mUpsideDownRotation = Surface.ROTATION_90;
2350 }
2351 } else {
Dianne Hackborn81e56d52011-05-26 00:55:58 -07002352 shortSize = width;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002353 longSize = height;
Dianne Hackborn9d132642011-04-21 17:26:39 -07002354 mPortraitRotation = Surface.ROTATION_0;
2355 mUpsideDownRotation = Surface.ROTATION_180;
Craig Mautner46ac6fa2013-08-01 10:06:34 -07002356 if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
Dianne Hackborn9d132642011-04-21 17:26:39 -07002357 mLandscapeRotation = Surface.ROTATION_270;
2358 mSeascapeRotation = Surface.ROTATION_90;
2359 } else {
2360 mLandscapeRotation = Surface.ROTATION_90;
2361 mSeascapeRotation = Surface.ROTATION_270;
2362 }
2363 }
Dianne Hackborn81e56d52011-05-26 00:55:58 -07002364
Daniel Sandler4a066c52012-04-20 14:49:13 -04002365 // SystemUI (status bar) layout policy
Dianne Hackborndde331c2012-08-03 14:01:57 -07002366 int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density;
Craig Mautner46ac6fa2013-08-01 10:06:34 -07002367 int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density;
Daniel Sandler4a066c52012-04-20 14:49:13 -04002368
Devin Kimd7b12b42014-05-05 14:34:58 -07002369 // Allow the navigation bar to move on non-square small devices (phones).
2370 mNavigationBarCanMove = width != height && shortSizeDp < 600;
Daniel Sandler36412a72011-08-04 09:35:13 -04002371
Craig Mautner46ac6fa2013-08-01 10:06:34 -07002372 mHasNavigationBar = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
Jorim Jaggi11c62e12016-04-05 20:41:21 -07002373
John Spurlock80f00c12013-06-13 11:10:51 -04002374 // Allow a system property to override this. Used by the emulator.
2375 // See also hasNavigationBar().
2376 String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
2377 if ("1".equals(navBarOverride)) {
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002378 mHasNavigationBar = false;
John Spurlock80f00c12013-06-13 11:10:51 -04002379 } else if ("0".equals(navBarOverride)) {
2380 mHasNavigationBar = true;
Daniel Sandler0c4ccff2011-10-19 16:39:14 -04002381 }
2382
Jeff Brown27f1d672012-10-17 18:32:34 -07002383 // For demo purposes, allow the rotation of the HDMI display to be controlled.
2384 // By default, HDMI locks rotation to landscape.
Erik Gilling9a41ef82011-09-26 19:21:03 -07002385 if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
Jeff Brownc82c89ed2013-04-17 17:18:15 -07002386 mDemoHdmiRotation = mPortraitRotation;
Erik Gilling9a41ef82011-09-26 19:21:03 -07002387 } else {
Jeff Brownc82c89ed2013-04-17 17:18:15 -07002388 mDemoHdmiRotation = mLandscapeRotation;
Erik Gilling9a41ef82011-09-26 19:21:03 -07002389 }
Jeff Brownc82c89ed2013-04-17 17:18:15 -07002390 mDemoHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", false);
Craig Mautner46ac6fa2013-08-01 10:06:34 -07002391
Chong Zhangae6119ff2014-11-11 18:54:39 -08002392 // For demo purposes, allow the rotation of the remote display to be controlled.
2393 // By default, remote display locks rotation to landscape.
2394 if ("portrait".equals(SystemProperties.get("persist.demo.remoterotation"))) {
2395 mDemoRotation = mPortraitRotation;
2396 } else {
2397 mDemoRotation = mLandscapeRotation;
2398 }
2399 mDemoRotationLock = SystemProperties.getBoolean(
2400 "persist.demo.rotationlock", false);
2401
Craig Mautner46ac6fa2013-08-01 10:06:34 -07002402 // Only force the default orientation if the screen is xlarge, at least 960dp x 720dp, per
2403 // http://developer.android.com/guide/practices/screens_support.html#range
Dean Hardingd12a8042017-10-10 14:46:26 -07002404 // For car, ignore the dp limitation. It's physically impossible to rotate the car's screen
2405 // so if the orientation is forced, we need to respect that no matter what.
Dake Gu95231212018-01-09 17:13:56 -08002406 final boolean isCar = mContext.getPackageManager().hasSystemFeature(
Dean Hardingd12a8042017-10-10 14:46:26 -07002407 PackageManager.FEATURE_AUTOMOTIVE);
Dake Gu95231212018-01-09 17:13:56 -08002408 // For TV, it's usually 960dp x 540dp, ignore the size limitation.
2409 // so if the orientation is forced, we need to respect that no matter what.
2410 final boolean isTv = mContext.getPackageManager().hasSystemFeature(
2411 PackageManager.FEATURE_LEANBACK);
2412 mForceDefaultOrientation = ((longSizeDp >= 960 && shortSizeDp >= 720) || isCar || isTv) &&
Craig Mautner46ac6fa2013-08-01 10:06:34 -07002413 res.getBoolean(com.android.internal.R.bool.config_forceDefaultOrientation) &&
2414 // For debug purposes the next line turns this feature off with:
2415 // $ adb shell setprop config.override_forced_orient true
2416 // $ adb shell wm size reset
2417 !"true".equals(SystemProperties.get("config.override_forced_orient"));
2418 }
2419
Alan Viverette5a0f4ec2013-10-07 15:10:29 -07002420 /**
2421 * @return whether the navigation bar can be hidden, e.g. the device has a
2422 * navigation bar and touch exploration is not enabled
2423 */
2424 private boolean canHideNavigationBar() {
Alan Viverette817f3cd2015-08-13 11:40:14 -04002425 return mHasNavigationBar;
Alan Viverette5a0f4ec2013-10-07 15:10:29 -07002426 }
2427
Craig Mautner46ac6fa2013-08-01 10:06:34 -07002428 @Override
2429 public boolean isDefaultOrientationForced() {
2430 return mForceDefaultOrientation;
Dianne Hackborn9d132642011-04-21 17:26:39 -07002431 }
2432
Dianne Hackbornc777e072010-02-12 13:07:59 -08002433 public void updateSettings() {
2434 ContentResolver resolver = mContext.getContentResolver();
2435 boolean updateRotation = false;
Dianne Hackbornc777e072010-02-12 13:07:59 -08002436 synchronized (mLock) {
Christopher Tate5e08af02012-09-21 17:17:22 -07002437 mEndcallBehavior = Settings.System.getIntForUser(resolver,
David Brownbaf8d092010-03-08 21:52:59 -08002438 Settings.System.END_BUTTON_BEHAVIOR,
Christopher Tate5e08af02012-09-21 17:17:22 -07002439 Settings.System.END_BUTTON_BEHAVIOR_DEFAULT,
2440 UserHandle.USER_CURRENT);
2441 mIncallPowerBehavior = Settings.Secure.getIntForUser(resolver,
David Brownbaf8d092010-03-08 21:52:59 -08002442 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
Christopher Tate5e08af02012-09-21 17:17:22 -07002443 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT,
2444 UserHandle.USER_CURRENT);
Bryce Leedb776ce2016-09-03 15:02:00 -07002445 mIncallBackBehavior = Settings.Secure.getIntForUser(resolver,
2446 Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR,
2447 Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR_DEFAULT,
2448 UserHandle.USER_CURRENT);
Siarhei Vishniakoue5e0d9f2018-03-05 20:09:08 -08002449 mSystemNavigationKeysEnabled = Settings.Secure.getIntForUser(resolver,
2450 Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED,
2451 0, UserHandle.USER_CURRENT) == 1;
Mike Digman55272862018-02-20 14:35:17 -08002452 mRingerToggleChord = Settings.Secure.getIntForUser(resolver,
2453 Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF,
2454 UserHandle.USER_CURRENT);
2455 if (!mContext.getResources()
2456 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) {
2457 mRingerToggleChord = Settings.Secure.VOLUME_HUSH_OFF;
2458 }
Mike Digmane14e6632018-01-11 10:43:08 -08002459 // Configure rotation suggestions.
2460 int showRotationSuggestions = Settings.Secure.getIntForUser(resolver,
2461 Settings.Secure.SHOW_ROTATION_SUGGESTIONS,
2462 Settings.Secure.SHOW_ROTATION_SUGGESTIONS_DEFAULT,
2463 UserHandle.USER_CURRENT);
2464 if (mShowRotationSuggestions != showRotationSuggestions) {
2465 mShowRotationSuggestions = showRotationSuggestions;
2466 updateOrientationListenerLp(); // Enable, disable the orientation listener
2467 }
2468
Jeff Browna20dda42014-05-27 20:57:24 -07002469 // Configure wake gesture.
2470 boolean wakeGestureEnabledSetting = Settings.Secure.getIntForUser(resolver,
2471 Settings.Secure.WAKE_GESTURE_ENABLED, 0,
2472 UserHandle.USER_CURRENT) != 0;
2473 if (mWakeGestureEnabledSetting != wakeGestureEnabledSetting) {
2474 mWakeGestureEnabledSetting = wakeGestureEnabledSetting;
2475 updateWakeGestureListenerLp();
2476 }
2477
Jeff Brown207673cd2012-06-05 17:47:11 -07002478 // Configure rotation lock.
Christopher Tate5e08af02012-09-21 17:17:22 -07002479 int userRotation = Settings.System.getIntForUser(resolver,
2480 Settings.System.USER_ROTATION, Surface.ROTATION_0,
2481 UserHandle.USER_CURRENT);
Jeff Brown207673cd2012-06-05 17:47:11 -07002482 if (mUserRotation != userRotation) {
2483 mUserRotation = userRotation;
2484 updateRotation = true;
2485 }
Christopher Tate5e08af02012-09-21 17:17:22 -07002486 int userRotationMode = Settings.System.getIntForUser(resolver,
2487 Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ?
Jeff Brown207673cd2012-06-05 17:47:11 -07002488 WindowManagerPolicy.USER_ROTATION_FREE :
2489 WindowManagerPolicy.USER_ROTATION_LOCKED;
2490 if (mUserRotationMode != userRotationMode) {
2491 mUserRotationMode = userRotationMode;
2492 updateRotation = true;
Dianne Hackbornc777e072010-02-12 13:07:59 -08002493 updateOrientationListenerLp();
2494 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -04002495
Dianne Hackbornc777e072010-02-12 13:07:59 -08002496 if (mSystemReady) {
Christopher Tate5e08af02012-09-21 17:17:22 -07002497 int pointerLocation = Settings.System.getIntForUser(resolver,
2498 Settings.System.POINTER_LOCATION, 0, UserHandle.USER_CURRENT);
Dianne Hackbornc777e072010-02-12 13:07:59 -08002499 if (mPointerLocationMode != pointerLocation) {
2500 mPointerLocationMode = pointerLocation;
Jeff Brown70825162012-03-28 17:27:48 -07002501 mHandler.sendEmptyMessage(pointerLocation != 0 ?
2502 MSG_ENABLE_POINTER_LOCATION : MSG_DISABLE_POINTER_LOCATION);
Dianne Hackbornc777e072010-02-12 13:07:59 -08002503 }
2504 }
2505 // use screen off timeout setting as the timeout for the lockscreen
Christopher Tate5e08af02012-09-21 17:17:22 -07002506 mLockScreenTimeout = Settings.System.getIntForUser(resolver,
2507 Settings.System.SCREEN_OFF_TIMEOUT, 0, UserHandle.USER_CURRENT);
2508 String imId = Settings.Secure.getStringForUser(resolver,
2509 Settings.Secure.DEFAULT_INPUT_METHOD, UserHandle.USER_CURRENT);
Dianne Hackbornc777e072010-02-12 13:07:59 -08002510 boolean hasSoftInput = imId != null && imId.length() > 0;
2511 if (mHasSoftInput != hasSoftInput) {
2512 mHasSoftInput = hasSoftInput;
2513 updateRotation = true;
2514 }
John Spurlockf1a36642013-10-12 17:50:42 -04002515 if (mImmersiveModeConfirmation != null) {
John Spurlock4355a532014-02-19 09:49:25 -05002516 mImmersiveModeConfirmation.loadSetting(mCurrentUserId);
John Spurlockd67ec252013-09-05 11:31:54 -04002517 }
tiger_huangcc6366d2015-06-29 17:17:30 +08002518 }
2519 synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
John Spurlockc6d1c602014-01-17 15:22:06 -05002520 PolicyControl.reloadFromSetting(mContext);
Dianne Hackbornc777e072010-02-12 13:07:59 -08002521 }
2522 if (updateRotation) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07002523 updateRotation(true);
Dianne Hackbornc777e072010-02-12 13:07:59 -08002524 }
Jeff Brown70825162012-03-28 17:27:48 -07002525 }
2526
Jeff Browna20dda42014-05-27 20:57:24 -07002527 private void updateWakeGestureListenerLp() {
2528 if (shouldEnableWakeGestureLp()) {
2529 mWakeGestureListener.requestWakeUpTrigger();
2530 } else {
2531 mWakeGestureListener.cancelWakeUpTrigger();
2532 }
2533 }
2534
2535 private boolean shouldEnableWakeGestureLp() {
Jeff Brown3ee549c2014-09-22 20:14:39 -07002536 return mWakeGestureEnabledSetting && !mAwake
Jeff Browna20dda42014-05-27 20:57:24 -07002537 && (!mLidControlsSleep || mLidState != LID_CLOSED)
2538 && mWakeGestureListener.isSupported();
2539 }
2540
Jeff Brown70825162012-03-28 17:27:48 -07002541 private void enablePointerLocation() {
2542 if (mPointerLocationView == null) {
2543 mPointerLocationView = new PointerLocationView(mContext);
2544 mPointerLocationView.setPrintCoords(false);
Dianne Hackbornc777e072010-02-12 13:07:59 -08002545 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
2546 WindowManager.LayoutParams.MATCH_PARENT,
2547 WindowManager.LayoutParams.MATCH_PARENT);
Jeff Brown3b2b3542010-10-15 00:54:27 -07002548 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
Jeff Brownbfcb60a2011-09-08 18:51:14 -07002549 lp.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN
2550 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
2551 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
2552 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
Adrian Roos7851ace2018-04-12 10:20:47 +02002553 lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
Jeff Brown90fc9052012-10-01 14:44:24 -07002554 if (ActivityManager.isHighEndGfx()) {
2555 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
2556 lp.privateFlags |=
2557 WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
2558 }
Dianne Hackbornc777e072010-02-12 13:07:59 -08002559 lp.format = PixelFormat.TRANSLUCENT;
2560 lp.setTitle("PointerLocation");
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002561 WindowManager wm = (WindowManager) mContext.getSystemService(WINDOW_SERVICE);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002562 lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
Jeff Brown70825162012-03-28 17:27:48 -07002563 wm.addView(mPointerLocationView, lp);
Michael Wrightc9c487e2013-11-07 18:55:09 -08002564 mWindowManagerFuncs.registerPointerEventListener(mPointerLocationView);
Dianne Hackbornc777e072010-02-12 13:07:59 -08002565 }
Dianne Hackbornc777e072010-02-12 13:07:59 -08002566 }
Jeff Brown70825162012-03-28 17:27:48 -07002567
2568 private void disablePointerLocation() {
Jeff Brown70825162012-03-28 17:27:48 -07002569 if (mPointerLocationView != null) {
Michael Wrightc9c487e2013-11-07 18:55:09 -08002570 mWindowManagerFuncs.unregisterPointerEventListener(mPointerLocationView);
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002571 WindowManager wm = (WindowManager) mContext.getSystemService(WINDOW_SERVICE);
Jeff Brown70825162012-03-28 17:27:48 -07002572 wm.removeView(mPointerLocationView);
2573 mPointerLocationView = null;
2574 }
2575 }
2576
Mike Lockwood2d1efbd2009-09-16 12:15:53 -04002577 private int readRotation(int resID) {
Mike Lockwood1753f7f2009-08-24 14:49:07 -07002578 try {
2579 int rotation = mContext.getResources().getInteger(resID);
2580 switch (rotation) {
2581 case 0:
2582 return Surface.ROTATION_0;
2583 case 90:
2584 return Surface.ROTATION_90;
2585 case 180:
2586 return Surface.ROTATION_180;
2587 case 270:
2588 return Surface.ROTATION_270;
Mike Lockwood1753f7f2009-08-24 14:49:07 -07002589 }
2590 } catch (Resources.NotFoundException e) {
Mike Lockwood2d1efbd2009-09-16 12:15:53 -04002591 // fall through
Mike Lockwood1753f7f2009-08-24 14:49:07 -07002592 }
Mike Lockwood2d1efbd2009-09-16 12:15:53 -04002593 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002594 }
2595
2596 /** {@inheritDoc} */
Craig Mautner88400d32012-09-30 12:35:45 -07002597 @Override
Dianne Hackbornc2293022013-02-06 23:14:49 -08002598 public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp) {
Adrian Roos4bef62e2018-03-21 19:52:09 +01002599 final int type = attrs.type;
2600 final boolean isRoundedCornerOverlay =
2601 (attrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;
2602
2603 if (isRoundedCornerOverlay && mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
2604 != PERMISSION_GRANTED) {
2605 return ADD_PERMISSION_DENIED;
2606 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08002607
2608 outAppOp[0] = AppOpsManager.OP_NONE;
2609
Wale Ogunwale74bf0652015-01-12 10:24:36 -08002610 if (!((type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW)
2611 || (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW)
2612 || (type >= FIRST_SYSTEM_WINDOW && type <= LAST_SYSTEM_WINDOW))) {
2613 return WindowManagerGlobal.ADD_INVALID_TYPE;
2614 }
2615
2616 if (type < FIRST_SYSTEM_WINDOW || type > LAST_SYSTEM_WINDOW) {
2617 // Window manager will make sure these are okay.
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08002618 return ADD_OKAY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002619 }
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08002620
2621 if (!isSystemAlertWindowType(type)) {
2622 switch (type) {
2623 case TYPE_TOAST:
2624 // Only apps that target older than O SDK can add window without a token, after
2625 // that we require a token so apps cannot add toasts directly as the token is
2626 // added by the notification system.
2627 // Window manager does the checking for this.
2628 outAppOp[0] = OP_TOAST_WINDOW;
2629 return ADD_OKAY;
2630 case TYPE_DREAM:
2631 case TYPE_INPUT_METHOD:
2632 case TYPE_WALLPAPER:
2633 case TYPE_PRESENTATION:
2634 case TYPE_PRIVATE_PRESENTATION:
2635 case TYPE_VOICE_INTERACTION:
2636 case TYPE_ACCESSIBILITY_OVERLAY:
2637 case TYPE_QS_DIALOG:
2638 // The window manager will check these.
2639 return ADD_OKAY;
2640 }
2641 return mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
2642 == PERMISSION_GRANTED ? ADD_OKAY : ADD_PERMISSION_DENIED;
2643 }
2644
2645 // Things get a little more interesting for alert windows...
2646 outAppOp[0] = OP_SYSTEM_ALERT_WINDOW;
2647
2648 final int callingUid = Binder.getCallingUid();
2649 // system processes will be automatically granted privilege to draw
2650 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
2651 return ADD_OKAY;
2652 }
2653
2654 ApplicationInfo appInfo;
2655 try {
Tony Mak22295fd2017-03-20 16:17:54 +00002656 appInfo = mContext.getPackageManager().getApplicationInfoAsUser(
2657 attrs.packageName,
2658 0 /* flags */,
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08002659 UserHandle.getUserId(callingUid));
2660 } catch (PackageManager.NameNotFoundException e) {
2661 appInfo = null;
2662 }
2663
2664 if (appInfo == null || (type != TYPE_APPLICATION_OVERLAY && appInfo.targetSdkVersion >= O)) {
2665 /**
2666 * Apps targeting >= {@link Build.VERSION_CODES#O} are required to hold
2667 * {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW} (system signature apps)
2668 * permission to add alert windows that aren't
2669 * {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY}.
2670 */
Wale Ogunwale5aa86832017-02-28 10:40:27 -08002671 return (mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
2672 == PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED;
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08002673 }
2674
2675 // check if user has enabled this operation. SecurityException will be thrown if this app
2676 // has not been allowed by the user
Peter Visontay96449f62017-12-11 18:50:03 +00002677 final int mode = mAppOpsManager.noteOpNoThrow(outAppOp[0], callingUid, attrs.packageName);
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08002678 switch (mode) {
2679 case AppOpsManager.MODE_ALLOWED:
2680 case AppOpsManager.MODE_IGNORED:
2681 // although we return ADD_OKAY for MODE_IGNORED, the added window will
2682 // actually be hidden in WindowManagerService
2683 return ADD_OKAY;
2684 case AppOpsManager.MODE_ERRORED:
2685 // Don't crash legacy apps
2686 if (appInfo.targetSdkVersion < M) {
2687 return ADD_OKAY;
2688 }
2689 return ADD_PERMISSION_DENIED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002690 default:
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08002691 // in the default mode, we will make a decision here based on
2692 // checkCallingPermission()
Wale Ogunwale5aa86832017-02-28 10:40:27 -08002693 return (mContext.checkCallingOrSelfPermission(SYSTEM_ALERT_WINDOW)
2694 == PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002695 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002696 }
Craig Mautner88400d32012-09-30 12:35:45 -07002697
2698 @Override
2699 public boolean checkShowToOwnerOnly(WindowManager.LayoutParams attrs) {
2700
2701 // If this switch statement is modified, modify the comment in the declarations of
2702 // the type in {@link WindowManager.LayoutParams} as well.
2703 switch (attrs.type) {
2704 default:
2705 // These are the windows that by default are shown only to the user that created
2706 // them. If this needs to be overridden, set
2707 // {@link WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS} in
2708 // {@link WindowManager.LayoutParams}. Note that permission
2709 // {@link android.Manifest.permission.INTERNAL_SYSTEM_WINDOW} is required as well.
2710 if ((attrs.privateFlags & PRIVATE_FLAG_SHOW_FOR_ALL_USERS) == 0) {
2711 return true;
2712 }
2713 break;
2714
2715 // These are the windows that by default are shown to all users. However, to
2716 // protect against spoofing, check permissions below.
2717 case TYPE_APPLICATION_STARTING:
2718 case TYPE_BOOT_PROGRESS:
2719 case TYPE_DISPLAY_OVERLAY:
Selim Cinekf83e8242015-05-19 18:08:14 -07002720 case TYPE_INPUT_CONSUMER:
Craig Mautner88400d32012-09-30 12:35:45 -07002721 case TYPE_KEYGUARD_DIALOG:
2722 case TYPE_MAGNIFICATION_OVERLAY:
2723 case TYPE_NAVIGATION_BAR:
2724 case TYPE_NAVIGATION_BAR_PANEL:
2725 case TYPE_PHONE:
2726 case TYPE_POINTER:
2727 case TYPE_PRIORITY_PHONE:
Craig Mautner88400d32012-09-30 12:35:45 -07002728 case TYPE_SEARCH_BAR:
2729 case TYPE_STATUS_BAR:
2730 case TYPE_STATUS_BAR_PANEL:
2731 case TYPE_STATUS_BAR_SUB_PANEL:
2732 case TYPE_SYSTEM_DIALOG:
Craig Mautner88400d32012-09-30 12:35:45 -07002733 case TYPE_VOLUME_OVERLAY:
Wale Ogunwale5b6714c2016-11-01 20:54:46 -07002734 case TYPE_PRESENTATION:
keunyounga446bf02013-06-21 19:07:57 -07002735 case TYPE_PRIVATE_PRESENTATION:
Filip Gruszczynski466f3212015-09-21 17:57:57 -07002736 case TYPE_DOCK_DIVIDER:
Craig Mautner88400d32012-09-30 12:35:45 -07002737 break;
2738 }
2739
2740 // Check if third party app has set window to system window type.
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08002741 return mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED;
Craig Mautner88400d32012-09-30 12:35:45 -07002742 }
2743
Craig Mautner967212c2013-04-13 21:10:58 -07002744 @Override
Wale Ogunwalec0b0f932017-11-01 12:51:43 -07002745 public void adjustWindowParamsLw(WindowState win, WindowManager.LayoutParams attrs,
2746 boolean hasStatusBarServicePermission) {
2747
2748 final boolean isScreenDecor = (attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0;
2749 if (mScreenDecorWindows.contains(win)) {
2750 if (!isScreenDecor) {
2751 // No longer has the flag set, so remove from the set.
2752 mScreenDecorWindows.remove(win);
2753 }
2754 } else if (isScreenDecor && hasStatusBarServicePermission) {
2755 mScreenDecorWindows.add(win);
2756 }
2757
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002758 switch (attrs.type) {
2759 case TYPE_SYSTEM_OVERLAY:
Jeff Brown3b2b3542010-10-15 00:54:27 -07002760 case TYPE_SECURE_SYSTEM_OVERLAY:
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002761 // These types of windows can't receive input events.
2762 attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
2763 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
Jeff Brownbfcb60a2011-09-08 18:51:14 -07002764 attrs.flags &= ~WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002765 break;
Adrian Roos75885972018-02-20 17:16:34 +01002766 case TYPE_DREAM:
Adrian Roos7e58a082018-03-09 16:40:56 +01002767 case TYPE_WALLPAPER:
2768 // Dreams and wallpapers don't have an app window token and can thus not be
2769 // letterboxed. Hence always let them extend under the cutout.
Adrian Roos75885972018-02-20 17:16:34 +01002770 attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
2771 break;
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002772 case TYPE_STATUS_BAR:
2773
2774 // If the Keyguard is in a hidden state (occluded by another window), we force to
2775 // remove the wallpaper and keyguard flag so that any change in-flight after setting
2776 // the keyguard as occluded wouldn't set these flags again.
2777 // See {@link #processKeyguardSetHiddenResultLw}.
Jorim Jaggife762342016-10-13 14:33:27 +02002778 if (mKeyguardOccluded) {
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002779 attrs.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
2780 attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
2781 }
2782 break;
Svetoslav Ganovaa076532016-08-01 19:16:43 -07002783
Muyuan Li36ca72c2016-08-06 20:24:06 -07002784 case TYPE_SCREENSHOT:
2785 attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
2786 break;
Svetoslav Ganovaa076532016-08-01 19:16:43 -07002787
2788 case TYPE_TOAST:
2789 // While apps should use the dedicated toast APIs to add such windows
2790 // it possible legacy apps to add the window directly. Therefore, we
2791 // make windows added directly by the app behave as a toast as much
2792 // as possible in terms of timeout and animation.
2793 if (attrs.hideTimeoutMilliseconds < 0
2794 || attrs.hideTimeoutMilliseconds > TOAST_WINDOW_TIMEOUT) {
2795 attrs.hideTimeoutMilliseconds = TOAST_WINDOW_TIMEOUT;
2796 }
2797 attrs.windowAnimations = com.android.internal.R.style.Animation_Toast;
2798 break;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002799 }
Adrian Roos38502112014-04-09 21:04:11 +02002800
2801 if (attrs.type != TYPE_STATUS_BAR) {
2802 // The status bar is the only window allowed to exhibit keyguard behavior.
2803 attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
2804 }
Adrian Roos77373982017-11-24 13:24:28 +01002805 }
Adrian Roosea562512014-05-05 13:33:03 +02002806
Adrian Roos77373982017-11-24 13:24:28 +01002807 private int getImpliedSysUiFlagsForLayout(LayoutParams attrs) {
2808 int impliedFlags = 0;
Ng Zhi Anc6617132017-09-22 09:15:29 -07002809 if ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) {
Adrian Roos77373982017-11-24 13:24:28 +01002810 impliedFlags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
Ng Zhi Anc6617132017-09-22 09:15:29 -07002811 }
2812 final boolean forceWindowDrawsStatusBarBackground =
2813 (attrs.privateFlags & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0;
2814 if ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
2815 || forceWindowDrawsStatusBarBackground
2816 && attrs.height == MATCH_PARENT && attrs.width == MATCH_PARENT) {
Adrian Roos77373982017-11-24 13:24:28 +01002817 impliedFlags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
Adrian Roosea562512014-05-05 13:33:03 +02002818 }
Adrian Roos77373982017-11-24 13:24:28 +01002819 return impliedFlags;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002820 }
RoboErik8a2cfc32014-05-16 11:19:38 -07002821
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002822 void readLidState() {
Jeff Brown2e7760e2012-04-11 15:14:55 -07002823 mLidState = mWindowManagerFuncs.getLidState();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002824 }
RoboErik8a2cfc32014-05-16 11:19:38 -07002825
Michael Wright3818c922014-09-02 13:59:07 -07002826 private void readCameraLensCoverState() {
2827 mCameraLensCoverState = mWindowManagerFuncs.getCameraLensCoverState();
2828 }
2829
Jeff Browndaa37532012-05-01 15:54:03 -07002830 private boolean isHidden(int accessibilityMode) {
2831 switch (accessibilityMode) {
2832 case 1:
2833 return mLidState == LID_CLOSED;
2834 case 2:
2835 return mLidState == LID_OPEN;
2836 default:
2837 return false;
Dianne Hackborn2862fff2009-09-15 22:56:29 -07002838 }
Dianne Hackborn2862fff2009-09-15 22:56:29 -07002839 }
Jeff Brownd04a88c2011-01-16 14:05:47 -08002840
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002841 /** {@inheritDoc} */
Craig Mautner967212c2013-04-13 21:10:58 -07002842 @Override
Jeff Browndaa37532012-05-01 15:54:03 -07002843 public void adjustConfigurationLw(Configuration config, int keyboardPresence,
2844 int navigationPresence) {
2845 mHaveBuiltInKeyboard = (keyboardPresence & PRESENCE_INTERNAL) != 0;
2846
Jeff Brownf71343d2013-05-31 17:59:11 -07002847 readConfigurationDependentBehaviors();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002848 readLidState();
Jeff Brownd04a88c2011-01-16 14:05:47 -08002849
Jeff Browndaa37532012-05-01 15:54:03 -07002850 if (config.keyboard == Configuration.KEYBOARD_NOKEYS
2851 || (keyboardPresence == PRESENCE_INTERNAL
2852 && isHidden(mLidKeyboardAccessibility))) {
Jeff Brownd04a88c2011-01-16 14:05:47 -08002853 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES;
Jeff Browndaa37532012-05-01 15:54:03 -07002854 if (!mHasSoftInput) {
2855 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_YES;
2856 }
Jeff Brownd04a88c2011-01-16 14:05:47 -08002857 }
2858
Jeff Browndaa37532012-05-01 15:54:03 -07002859 if (config.navigation == Configuration.NAVIGATION_NONAV
2860 || (navigationPresence == PRESENCE_INTERNAL
2861 && isHidden(mLidNavigationAccessibility))) {
Jeff Brownd04a88c2011-01-16 14:05:47 -08002862 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_YES;
Jeff Brownd04a88c2011-01-16 14:05:47 -08002863 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002864 }
Jeff Brownd04a88c2011-01-16 14:05:47 -08002865
Jorim Jaggi11c62e12016-04-05 20:41:21 -07002866 @Override
Adrian Roos2f1a90b2018-01-09 17:28:49 +01002867 public void onOverlayChangedLw() {
2868 onConfigurationChanged();
2869 }
2870
2871 @Override
Jorim Jaggi11c62e12016-04-05 20:41:21 -07002872 public void onConfigurationChanged() {
Andrii Kulian3a507b52016-09-19 18:14:12 -07002873 // TODO(multi-display): Define policy for secondary displays.
Adrian Roose1856fe2017-11-24 19:39:12 +01002874 Context uiContext = getSystemUiContext();
Jason Monkf506bf32017-08-23 10:56:34 -04002875 final Resources res = uiContext.getResources();
Jorim Jaggi11c62e12016-04-05 20:41:21 -07002876
Adrian Roos22af6502018-02-22 16:57:08 +01002877 mStatusBarHeightForRotation[mPortraitRotation] =
2878 mStatusBarHeightForRotation[mUpsideDownRotation] = res.getDimensionPixelSize(
2879 com.android.internal.R.dimen.status_bar_height_portrait);
2880 mStatusBarHeightForRotation[mLandscapeRotation] =
2881 mStatusBarHeightForRotation[mSeascapeRotation] = res.getDimensionPixelSize(
2882 com.android.internal.R.dimen.status_bar_height_landscape);
Jorim Jaggi11c62e12016-04-05 20:41:21 -07002883
2884 // Height of the navigation bar when presented horizontally at bottom
2885 mNavigationBarHeightForRotationDefault[mPortraitRotation] =
2886 mNavigationBarHeightForRotationDefault[mUpsideDownRotation] =
2887 res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height);
2888 mNavigationBarHeightForRotationDefault[mLandscapeRotation] =
2889 mNavigationBarHeightForRotationDefault[mSeascapeRotation] = res.getDimensionPixelSize(
2890 com.android.internal.R.dimen.navigation_bar_height_landscape);
2891
2892 // Width of the navigation bar when presented vertically along one side
2893 mNavigationBarWidthForRotationDefault[mPortraitRotation] =
2894 mNavigationBarWidthForRotationDefault[mUpsideDownRotation] =
2895 mNavigationBarWidthForRotationDefault[mLandscapeRotation] =
2896 mNavigationBarWidthForRotationDefault[mSeascapeRotation] =
2897 res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);
2898
Justin Paupore01915a12016-09-28 17:41:26 -07002899 if (ALTERNATE_CAR_MODE_NAV_SIZE) {
2900 // Height of the navigation bar when presented horizontally at bottom
2901 mNavigationBarHeightForRotationInCarMode[mPortraitRotation] =
2902 mNavigationBarHeightForRotationInCarMode[mUpsideDownRotation] =
2903 res.getDimensionPixelSize(
2904 com.android.internal.R.dimen.navigation_bar_height_car_mode);
2905 mNavigationBarHeightForRotationInCarMode[mLandscapeRotation] =
2906 mNavigationBarHeightForRotationInCarMode[mSeascapeRotation] = res.getDimensionPixelSize(
2907 com.android.internal.R.dimen.navigation_bar_height_landscape_car_mode);
Jorim Jaggi11c62e12016-04-05 20:41:21 -07002908
Justin Paupore01915a12016-09-28 17:41:26 -07002909 // Width of the navigation bar when presented vertically along one side
2910 mNavigationBarWidthForRotationInCarMode[mPortraitRotation] =
2911 mNavigationBarWidthForRotationInCarMode[mUpsideDownRotation] =
2912 mNavigationBarWidthForRotationInCarMode[mLandscapeRotation] =
2913 mNavigationBarWidthForRotationInCarMode[mSeascapeRotation] =
2914 res.getDimensionPixelSize(
2915 com.android.internal.R.dimen.navigation_bar_width_car_mode);
2916 }
Jorim Jaggi11c62e12016-04-05 20:41:21 -07002917 }
2918
Adrian Roose1856fe2017-11-24 19:39:12 +01002919 @VisibleForTesting
2920 Context getSystemUiContext() {
2921 return ActivityThread.currentActivityThread().getSystemUiContext();
2922 }
2923
Craig Mautner46ac6fa2013-08-01 10:06:34 -07002924 @Override
Dianne Hackbornabe0da02009-09-18 01:55:39 -07002925 public int getMaxWallpaperLayer() {
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08002926 return getWindowLayerFromTypeLw(TYPE_STATUS_BAR);
Dianne Hackbornabe0da02009-09-18 01:55:39 -07002927 }
2928
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -08002929 private int getNavigationBarWidth(int rotation, int uiMode) {
Justin Paupore01915a12016-09-28 17:41:26 -07002930 if (ALTERNATE_CAR_MODE_NAV_SIZE && (uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_CAR) {
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -08002931 return mNavigationBarWidthForRotationInCarMode[rotation];
2932 } else {
2933 return mNavigationBarWidthForRotationDefault[rotation];
2934 }
2935 }
2936
Craig Mautner46ac6fa2013-08-01 10:06:34 -07002937 @Override
Andrii Kuliandb8e1062016-11-15 18:30:27 -08002938 public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
Adrian Roos11c25582018-02-19 18:06:36 +01002939 int displayId, DisplayCutout displayCutout) {
2940 int width = fullWidth;
Andrii Kuliandb8e1062016-11-15 18:30:27 -08002941 // TODO(multi-display): Support navigation bar on secondary displays.
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02002942 if (displayId == DEFAULT_DISPLAY && mHasNavigationBar) {
Dianne Hackborn077ee852012-04-09 16:27:07 -07002943 // For a basic navigation bar, when we are in landscape mode we place
2944 // the navigation bar to the side.
Daniel Sandler4a066c52012-04-20 14:49:13 -04002945 if (mNavigationBarCanMove && fullWidth > fullHeight) {
Adrian Roos11c25582018-02-19 18:06:36 +01002946 width -= getNavigationBarWidth(rotation, uiMode);
Dianne Hackborn077ee852012-04-09 16:27:07 -07002947 }
Dianne Hackborn1f903c32011-09-13 19:18:06 -07002948 }
Adrian Roos11c25582018-02-19 18:06:36 +01002949 if (displayCutout != null) {
2950 width -= displayCutout.getSafeInsetLeft() + displayCutout.getSafeInsetRight();
2951 }
2952 return width;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002953 }
2954
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -08002955 private int getNavigationBarHeight(int rotation, int uiMode) {
Justin Paupore01915a12016-09-28 17:41:26 -07002956 if (ALTERNATE_CAR_MODE_NAV_SIZE && (uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_CAR) {
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -08002957 return mNavigationBarHeightForRotationInCarMode[rotation];
2958 } else {
2959 return mNavigationBarHeightForRotationDefault[rotation];
2960 }
2961 }
2962
Jose Lima9546b202014-07-02 17:21:51 -07002963 @Override
Andrii Kuliandb8e1062016-11-15 18:30:27 -08002964 public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
Adrian Roos11c25582018-02-19 18:06:36 +01002965 int displayId, DisplayCutout displayCutout) {
2966 int height = fullHeight;
Andrii Kuliandb8e1062016-11-15 18:30:27 -08002967 // TODO(multi-display): Support navigation bar on secondary displays.
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02002968 if (displayId == DEFAULT_DISPLAY && mHasNavigationBar) {
Dianne Hackborn077ee852012-04-09 16:27:07 -07002969 // For a basic navigation bar, when we are in portrait mode we place
2970 // the navigation bar to the bottom.
Daniel Sandler4a066c52012-04-20 14:49:13 -04002971 if (!mNavigationBarCanMove || fullWidth < fullHeight) {
Adrian Roos11c25582018-02-19 18:06:36 +01002972 height -= getNavigationBarHeight(rotation, uiMode);
Dianne Hackborn077ee852012-04-09 16:27:07 -07002973 }
2974 }
Adrian Roos11c25582018-02-19 18:06:36 +01002975 if (displayCutout != null) {
2976 height -= displayCutout.getSafeInsetTop() + displayCutout.getSafeInsetBottom();
2977 }
2978 return height;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07002979 }
2980
Jose Lima9546b202014-07-02 17:21:51 -07002981 @Override
Andrii Kuliandb8e1062016-11-15 18:30:27 -08002982 public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
Adrian Roos11c25582018-02-19 18:06:36 +01002983 int displayId, DisplayCutout displayCutout) {
2984 return getNonDecorDisplayWidth(fullWidth, fullHeight, rotation, uiMode, displayId,
2985 displayCutout);
Dianne Hackborn69cb8752011-05-19 18:13:32 -07002986 }
2987
Jose Lima9546b202014-07-02 17:21:51 -07002988 @Override
Andrii Kuliandb8e1062016-11-15 18:30:27 -08002989 public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
Adrian Roos11c25582018-02-19 18:06:36 +01002990 int displayId, DisplayCutout displayCutout) {
John Spurlock80f00c12013-06-13 11:10:51 -04002991 // There is a separate status bar at the top of the display. We don't count that as part
2992 // of the fixed decor, since it can hide; however, for purposes of configurations,
Dianne Hackborn077ee852012-04-09 16:27:07 -07002993 // we do want to exclude it since applications can't generally use that part
2994 // of the screen.
Andrii Kuliandb8e1062016-11-15 18:30:27 -08002995 // TODO(multi-display): Support status bars on secondary displays.
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02002996 if (displayId == DEFAULT_DISPLAY) {
Adrian Roos22af6502018-02-22 16:57:08 +01002997 int statusBarHeight = mStatusBarHeightForRotation[rotation];
Adrian Roos11c25582018-02-19 18:06:36 +01002998 if (displayCutout != null) {
2999 // If there is a cutout, it may already have accounted for some part of the status
3000 // bar height.
Adrian Roos22af6502018-02-22 16:57:08 +01003001 statusBarHeight = Math.max(0, statusBarHeight - displayCutout.getSafeInsetTop());
Adrian Roos11c25582018-02-19 18:06:36 +01003002 }
3003 return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation, uiMode, displayId,
3004 displayCutout) - statusBarHeight;
Andrii Kuliandb8e1062016-11-15 18:30:27 -08003005 }
3006 return fullHeight;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003007 }
3008
Craig Mautnera3f4bf52012-10-10 20:37:48 -07003009 @Override
Jorim Jaggi0d674622014-05-21 01:34:15 +02003010 public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
3011 return attrs.type == TYPE_STATUS_BAR;
3012 }
3013
3014 @Override
Jorim Jaggife762342016-10-13 14:33:27 +02003015 public boolean canBeHiddenByKeyguardLw(WindowState win) {
3016 switch (win.getAttrs().type) {
Craig Mautnera3f4bf52012-10-10 20:37:48 -07003017 case TYPE_STATUS_BAR:
3018 case TYPE_NAVIGATION_BAR:
3019 case TYPE_WALLPAPER:
3020 case TYPE_DREAM:
Craig Mautnera3f4bf52012-10-10 20:37:48 -07003021 return false;
3022 default:
Adrian Roos461829d2015-06-03 14:41:18 -07003023 // Hide only windows below the keyguard host window.
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08003024 return getWindowLayerLw(win) < getWindowLayerFromTypeLw(TYPE_STATUS_BAR);
Craig Mautnera3f4bf52012-10-10 20:37:48 -07003025 }
Dianne Hackborn01ad2f42009-09-24 19:24:56 -07003026 }
Craig Mautner8e4df6c2012-05-23 16:57:23 -07003027
Jorim Jaggife762342016-10-13 14:33:27 +02003028 private boolean shouldBeHiddenByKeyguard(WindowState win, WindowState imeTarget) {
3029
3030 // Keyguard visibility of window from activities are determined over activity visibility.
3031 if (win.getAppToken() != null) {
3032 return false;
3033 }
3034
3035 final LayoutParams attrs = win.getAttrs();
3036 final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleLw() &&
3037 ((imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0
3038 || !canBeHiddenByKeyguardLw(imeTarget));
3039
3040 // Show IME over the keyguard if the target allows it
3041 boolean allowWhenLocked = (win.isInputMethodWindow() || imeTarget == this)
Jorim Jaggi98a9d202018-03-26 16:17:07 +02003042 && showImeOverKeyguard;
Jorim Jaggife762342016-10-13 14:33:27 +02003043
3044 if (isKeyguardLocked() && isKeyguardOccluded()) {
3045 // Show SHOW_WHEN_LOCKED windows if Keyguard is occluded.
3046 allowWhenLocked |= (attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
3047 // Show error dialogs over apps that are shown on lockscreen
3048 || (attrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0;
3049 }
3050
3051 boolean keyguardLocked = isKeyguardLocked();
3052 boolean hideDockDivider = attrs.type == TYPE_DOCK_DIVIDER
Wale Ogunwale44f036f2017-09-29 05:09:09 -07003053 && !mWindowManagerInternal.isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02003054 return (keyguardLocked && !allowWhenLocked && win.getDisplayId() == DEFAULT_DISPLAY)
Jorim Jaggife762342016-10-13 14:33:27 +02003055 || hideDockDivider;
Craig Mautner7d7808f2014-09-11 18:02:38 -07003056 }
3057
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003058 /** {@inheritDoc} */
Craig Mautner8e4df6c2012-05-23 16:57:23 -07003059 @Override
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08003060 public StartingSurface addSplashScreen(IBinder appToken, String packageName, int theme,
3061 CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, int icon,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003062 int logo, int windowFlags, Configuration overrideConfig, int displayId) {
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08003063 if (!SHOW_SPLASH_SCREENS) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003064 return null;
3065 }
3066 if (packageName == null) {
3067 return null;
3068 }
Craig Mautner8e4df6c2012-05-23 16:57:23 -07003069
Mathias Jeppssond1443e92012-08-24 15:25:32 +02003070 WindowManager wm = null;
3071 View view = null;
3072
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003073 try {
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003074 Context context = mContext;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08003075 if (DEBUG_SPLASH_SCREEN) Slog.d(TAG, "addSplashScreen " + packageName
Craig Mautner6fbda632012-07-03 09:26:39 -07003076 + ": nonLocalizedLabel=" + nonLocalizedLabel + " theme="
3077 + Integer.toHexString(theme));
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003078
3079 // Obtain proper context to launch on the right display.
3080 final Context displayContext = getDisplayContext(context, displayId);
3081 if (displayContext == null) {
3082 // Can't show splash screen on requested display, so skip showing at all.
3083 return null;
3084 }
3085 context = displayContext;
3086
Dianne Hackborn247fe742011-01-08 17:25:57 -08003087 if (theme != context.getThemeResId() || labelRes != 0) {
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003088 try {
Robert Carr7ad24ba2017-06-20 17:26:06 -07003089 context = context.createPackageContext(packageName, CONTEXT_RESTRICTED);
Dianne Hackborn247fe742011-01-08 17:25:57 -08003090 context.setTheme(theme);
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003091 } catch (PackageManager.NameNotFoundException e) {
3092 // Ignore
3093 }
3094 }
Craig Mautner8e4df6c2012-05-23 16:57:23 -07003095
Andrii Kuliana8a9bc52016-10-14 11:00:13 -07003096 if (overrideConfig != null && !overrideConfig.equals(EMPTY)) {
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08003097 if (DEBUG_SPLASH_SCREEN) Slog.d(TAG, "addSplashScreen: creating context based"
3098 + " on overrideConfig" + overrideConfig + " for splash screen");
Wale Ogunwaledfc18622016-04-16 15:08:48 -07003099 final Context overrideContext = context.createConfigurationContext(overrideConfig);
3100 overrideContext.setTheme(theme);
3101 final TypedArray typedArray = overrideContext.obtainStyledAttributes(
3102 com.android.internal.R.styleable.Window);
3103 final int resId = typedArray.getResourceId(R.styleable.Window_windowBackground, 0);
3104 if (resId != 0 && overrideContext.getDrawable(resId) != null) {
3105 // We want to use the windowBackground for the override context if it is
3106 // available, otherwise we use the default one to make sure a themed starting
3107 // window is displayed for the app.
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08003108 if (DEBUG_SPLASH_SCREEN) Slog.d(TAG, "addSplashScreen: apply overrideConfig"
Wale Ogunwaledfc18622016-04-16 15:08:48 -07003109 + overrideConfig + " to starting window resId=" + resId);
3110 context = overrideContext;
3111 }
Jorim Jaggi7d0d1022017-02-23 15:35:51 +01003112 typedArray.recycle();
Wale Ogunwaledfc18622016-04-16 15:08:48 -07003113 }
3114
3115 final PhoneWindow win = new PhoneWindow(context);
Jorim Jaggia16cc152015-06-01 16:55:05 -07003116 win.setIsStartingWindow(true);
Craig Mautner8e4df6c2012-05-23 16:57:23 -07003117
Phil Weaver155edc62016-06-09 10:24:53 -07003118 CharSequence label = context.getResources().getText(labelRes, null);
3119 // Only change the accessibility title if the label is localized
3120 if (label != null) {
3121 win.setTitle(label, true);
3122 } else {
3123 win.setTitle(nonLocalizedLabel, false);
3124 }
Craig Mautner8e4df6c2012-05-23 16:57:23 -07003125
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003126 win.setType(
3127 WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
Adrian Roos602c68e2015-04-24 16:03:47 -07003128
3129 synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
3130 // Assumes it's safe to show starting windows of launched apps while
3131 // the keyguard is being hidden. This is okay because starting windows never show
3132 // secret information.
Jorim Jaggife762342016-10-13 14:33:27 +02003133 if (mKeyguardOccluded) {
Adrian Roos602c68e2015-04-24 16:03:47 -07003134 windowFlags |= FLAG_SHOW_WHEN_LOCKED;
3135 }
3136 }
3137
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003138 // Force the window flags: this is a fake window, so it is not really
3139 // touchable or focusable by the user. We also add in the ALT_FOCUSABLE_IM
3140 // flag because we do know that the next window will take input
3141 // focus, so we want to get the IME window up on top of us right away.
3142 win.setFlags(
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003143 windowFlags|
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003144 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
3145 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
3146 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003147 windowFlags|
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003148 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
3149 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
3150 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
Craig Mautner8e4df6c2012-05-23 16:57:23 -07003151
Adam Powell04fe6eb2013-05-31 14:39:48 -07003152 win.setDefaultIcon(icon);
3153 win.setDefaultLogo(logo);
3154
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003155 win.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07003156 WindowManager.LayoutParams.MATCH_PARENT);
Craig Mautner8e4df6c2012-05-23 16:57:23 -07003157
Phil Weaver266ed9a2016-06-08 00:34:40 +00003158 final WindowManager.LayoutParams params = win.getAttributes();
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003159 params.token = appToken;
3160 params.packageName = packageName;
3161 params.windowAnimations = win.getWindowStyle().getResourceId(
3162 com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
John Reck61375a82014-09-18 19:27:48 +00003163 params.privateFlags |=
3164 WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED;
Craig Mautner88400d32012-09-30 12:35:45 -07003165 params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
Adam Lesinski95c42972013-10-02 10:13:27 -07003166
3167 if (!compatInfo.supportsScreen()) {
3168 params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
3169 }
3170
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08003171 params.setTitle("Splash Screen " + packageName);
Jorim Jaggi7d0d1022017-02-23 15:35:51 +01003172 addSplashscreenContent(win, context);
3173
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003174 wm = (WindowManager) context.getSystemService(WINDOW_SERVICE);
Mathias Jeppssond1443e92012-08-24 15:25:32 +02003175 view = win.getDecorView();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003176
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08003177 if (DEBUG_SPLASH_SCREEN) Slog.d(TAG, "Adding splash screen window for "
Wale Ogunwaledfc18622016-04-16 15:08:48 -07003178 + packageName + " / " + appToken + ": " + (view.getParent() != null ? view : null));
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003179
3180 wm.addView(view, params);
3181
3182 // Only return the view if it was successfully added to the
3183 // window manager... which we can tell by it having a parent.
Jorim Jaggi02886a82016-12-06 09:10:06 -08003184 return view.getParent() != null ? new SplashScreenSurface(view, appToken) : null;
Jeff Brown98365d72012-08-19 20:30:52 -07003185 } catch (WindowManager.BadTokenException e) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003186 // ignore
Craig Mautner42bf39e2014-02-21 16:46:22 -08003187 Log.w(TAG, appToken + " already running, starting window not displayed. " +
3188 e.getMessage());
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003189 } catch (RuntimeException e) {
3190 // don't crash if something else bad happens, for example a
3191 // failure loading resources because we are loading from an app
3192 // on external storage that has been unmounted.
3193 Log.w(TAG, appToken + " failed creating starting window", e);
Mathias Jeppssond1443e92012-08-24 15:25:32 +02003194 } finally {
3195 if (view != null && view.getParent() == null) {
3196 Log.w(TAG, "view not successfully added to wm, removing view");
3197 wm.removeViewImmediate(view);
3198 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003199 }
3200
3201 return null;
3202 }
3203
Jorim Jaggi7d0d1022017-02-23 15:35:51 +01003204 private void addSplashscreenContent(PhoneWindow win, Context ctx) {
3205 final TypedArray a = ctx.obtainStyledAttributes(R.styleable.Window);
3206 final int resId = a.getResourceId(R.styleable.Window_windowSplashscreenContent, 0);
3207 a.recycle();
3208 if (resId == 0) {
3209 return;
3210 }
3211 final Drawable drawable = ctx.getDrawable(resId);
3212 if (drawable == null) {
3213 return;
3214 }
3215
3216 // We wrap this into a view so the system insets get applied to the drawable.
3217 final View v = new View(ctx);
3218 v.setBackground(drawable);
3219 win.setContentView(v);
3220 }
3221
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003222 /** Obtain proper context for showing splash screen on the provided display. */
3223 private Context getDisplayContext(Context context, int displayId) {
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02003224 if (displayId == DEFAULT_DISPLAY) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003225 // The default context fits.
3226 return context;
3227 }
3228
3229 final DisplayManager dm = (DisplayManager) context.getSystemService(DISPLAY_SERVICE);
3230 final Display targetDisplay = dm.getDisplay(displayId);
3231 if (targetDisplay == null) {
3232 // Failed to obtain the non-default display where splash screen should be shown,
3233 // lets not show at all.
3234 return null;
3235 }
3236
3237 return context.createDisplayContext(targetDisplay);
3238 }
3239
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003240 /**
3241 * Preflight adding a window to the system.
RoboErik8a2cfc32014-05-16 11:19:38 -07003242 *
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003243 * Currently enforces that three window types are singletons:
3244 * <ul>
3245 * <li>STATUS_BAR_TYPE</li>
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003246 * <li>KEYGUARD_TYPE</li>
3247 * </ul>
RoboErik8a2cfc32014-05-16 11:19:38 -07003248 *
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003249 * @param win The window to be added
3250 * @param attrs Information about the window to be added
RoboErik8a2cfc32014-05-16 11:19:38 -07003251 *
Jeff Brown98365d72012-08-19 20:30:52 -07003252 * @return If ok, WindowManagerImpl.ADD_OKAY. If too many singletons,
3253 * WindowManagerImpl.ADD_MULTIPLE_SINGLETON
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003254 */
Jose Lima9546b202014-07-02 17:21:51 -07003255 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003256 public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) {
Wale Ogunwalec0b0f932017-11-01 12:51:43 -07003257
3258 if ((attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0) {
3259 mContext.enforceCallingOrSelfPermission(
3260 android.Manifest.permission.STATUS_BAR_SERVICE,
3261 "PhoneWindowManager");
3262 mScreenDecorWindows.add(win);
3263 }
3264
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003265 switch (attrs.type) {
3266 case TYPE_STATUS_BAR:
Joe Onorato8bc6c512010-06-04 16:21:12 -04003267 mContext.enforceCallingOrSelfPermission(
3268 android.Manifest.permission.STATUS_BAR_SERVICE,
3269 "PhoneWindowManager");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003270 if (mStatusBar != null) {
Dianne Hackbornf87d1962012-04-04 12:48:24 -07003271 if (mStatusBar.isAlive()) {
Jeff Brown98365d72012-08-19 20:30:52 -07003272 return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07003273 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003274 }
3275 mStatusBar = win;
John Spurlock27735a42013-08-14 17:57:38 -04003276 mStatusBarController.setWindow(win);
Jorim Jaggi9ba2e102017-04-04 12:51:03 +02003277 setKeyguardOccludedLw(mKeyguardOccluded, true /* force */);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003278 break;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04003279 case TYPE_NAVIGATION_BAR:
3280 mContext.enforceCallingOrSelfPermission(
3281 android.Manifest.permission.STATUS_BAR_SERVICE,
3282 "PhoneWindowManager");
Dianne Hackbornf87d1962012-04-04 12:48:24 -07003283 if (mNavigationBar != null) {
3284 if (mNavigationBar.isAlive()) {
Jeff Brown98365d72012-08-19 20:30:52 -07003285 return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07003286 }
3287 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -04003288 mNavigationBar = win;
John Spurlock27735a42013-08-14 17:57:38 -04003289 mNavigationBarController.setWindow(win);
Casey Burkhardt048c2bc2016-12-08 16:09:20 -08003290 mNavigationBarController.setOnBarVisibilityChangedListener(
Casey Burkhardt469a2082017-06-13 20:12:42 -07003291 mNavBarVisibilityListener, true);
Craig Mautnereda67292013-04-28 13:50:14 -07003292 if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
Daniel Sandler8956dbb2011-04-22 07:55:02 -04003293 break;
Jim Millere898ac52012-04-06 17:10:57 -07003294 case TYPE_NAVIGATION_BAR_PANEL:
Dianne Hackborn08743722009-12-21 12:16:51 -08003295 case TYPE_STATUS_BAR_PANEL:
Joe Onorato29fc2c92010-11-24 10:26:50 -08003296 case TYPE_STATUS_BAR_SUB_PANEL:
Jorim Jaggi225d3b52015-04-01 11:18:57 -07003297 case TYPE_VOICE_INTERACTION_STARTING:
Joe Onorato29fc2c92010-11-24 10:26:50 -08003298 mContext.enforceCallingOrSelfPermission(
3299 android.Manifest.permission.STATUS_BAR_SERVICE,
3300 "PhoneWindowManager");
Joe Onorato29fc2c92010-11-24 10:26:50 -08003301 break;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003302 }
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08003303 return ADD_OKAY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003304 }
3305
3306 /** {@inheritDoc} */
Jose Lima9546b202014-07-02 17:21:51 -07003307 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003308 public void removeWindowLw(WindowState win) {
3309 if (mStatusBar == win) {
3310 mStatusBar = null;
John Spurlock27735a42013-08-14 17:57:38 -04003311 mStatusBarController.setWindow(null);
Jorim Jaggi73294b62016-10-26 18:02:36 -07003312 } else if (mNavigationBar == win) {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04003313 mNavigationBar = null;
John Spurlock27735a42013-08-14 17:57:38 -04003314 mNavigationBarController.setWindow(null);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003315 }
Wale Ogunwalec0b0f932017-11-01 12:51:43 -07003316 mScreenDecorWindows.remove(win);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003317 }
3318
3319 static final boolean PRINT_ANIM = false;
RoboErik8a2cfc32014-05-16 11:19:38 -07003320
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003321 /** {@inheritDoc} */
Craig Mautner4b71aa12012-12-27 17:20:01 -08003322 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003323 public int selectAnimationLw(WindowState win, int transit) {
3324 if (PRINT_ANIM) Log.i(TAG, "selectAnimation in " + win
3325 + ": transit=" + transit);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07003326 if (win == mStatusBar) {
Jorim Jaggi67b29d52017-06-09 18:00:00 -07003327 final boolean isKeyguard = (win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
3328 final boolean expanded = win.getAttrs().height == MATCH_PARENT
3329 && win.getAttrs().width == MATCH_PARENT;
3330 if (isKeyguard || expanded) {
3331 return -1;
3332 }
Craig Mautner4b71aa12012-12-27 17:20:01 -08003333 if (transit == TRANSIT_EXIT
3334 || transit == TRANSIT_HIDE) {
Jorim Jaggi67b29d52017-06-09 18:00:00 -07003335 return R.anim.dock_top_exit;
Craig Mautner4b71aa12012-12-27 17:20:01 -08003336 } else if (transit == TRANSIT_ENTER
3337 || transit == TRANSIT_SHOW) {
Jorim Jaggi67b29d52017-06-09 18:00:00 -07003338 return R.anim.dock_top_enter;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07003339 }
3340 } else if (win == mNavigationBar) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07003341 if (win.getAttrs().windowAnimations != 0) {
3342 return 0;
3343 }
Adrian Roos85d202b2016-06-02 16:27:47 -07003344 // This can be on either the bottom or the right or the left.
3345 if (mNavigationBarPosition == NAV_BAR_BOTTOM) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08003346 if (transit == TRANSIT_EXIT
3347 || transit == TRANSIT_HIDE) {
Jorim Jaggi48832812016-09-06 12:38:23 -07003348 if (isKeyguardShowingAndNotOccluded()) {
3349 return R.anim.dock_bottom_exit_keyguard;
3350 } else {
3351 return R.anim.dock_bottom_exit;
3352 }
Craig Mautner4b71aa12012-12-27 17:20:01 -08003353 } else if (transit == TRANSIT_ENTER
3354 || transit == TRANSIT_SHOW) {
Dianne Hackbornf87d1962012-04-04 12:48:24 -07003355 return R.anim.dock_bottom_enter;
3356 }
Adrian Roos85d202b2016-06-02 16:27:47 -07003357 } else if (mNavigationBarPosition == NAV_BAR_RIGHT) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08003358 if (transit == TRANSIT_EXIT
3359 || transit == TRANSIT_HIDE) {
Dianne Hackbornf87d1962012-04-04 12:48:24 -07003360 return R.anim.dock_right_exit;
Craig Mautner4b71aa12012-12-27 17:20:01 -08003361 } else if (transit == TRANSIT_ENTER
3362 || transit == TRANSIT_SHOW) {
Dianne Hackbornf87d1962012-04-04 12:48:24 -07003363 return R.anim.dock_right_enter;
3364 }
Adrian Roos85d202b2016-06-02 16:27:47 -07003365 } else if (mNavigationBarPosition == NAV_BAR_LEFT) {
3366 if (transit == TRANSIT_EXIT
3367 || transit == TRANSIT_HIDE) {
3368 return R.anim.dock_left_exit;
3369 } else if (transit == TRANSIT_ENTER
3370 || transit == TRANSIT_SHOW) {
3371 return R.anim.dock_left_enter;
3372 }
Dianne Hackbornf87d1962012-04-04 12:48:24 -07003373 }
Filip Gruszczynski57f76f12015-11-04 16:10:54 -08003374 } else if (win.getAttrs().type == TYPE_DOCK_DIVIDER) {
Jorim Jaggi81ba11e2016-02-03 22:04:22 -08003375 return selectDockedDividerAnimationLw(win, transit);
Craig Mautner4b71aa12012-12-27 17:20:01 -08003376 }
3377
3378 if (transit == TRANSIT_PREVIEW_DONE) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003379 if (win.hasAppShownWindows()) {
3380 if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT");
3381 return com.android.internal.R.anim.app_starting_exit;
3382 }
Dianne Hackborn7ad44382012-10-18 17:46:00 -07003383 } else if (win.getAttrs().type == TYPE_DREAM && mDreamingLockscreen
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07003384 && transit == TRANSIT_ENTER) {
3385 // Special case: we are animating in a dream, while the keyguard
3386 // is shown. We don't want an animation on the dream, because
3387 // we need it shown immediately with the keyguard animating away
3388 // to reveal it.
3389 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003390 }
3391
3392 return 0;
3393 }
3394
Jorim Jaggi81ba11e2016-02-03 22:04:22 -08003395 private int selectDockedDividerAnimationLw(WindowState win, int transit) {
3396 int insets = mWindowManagerFuncs.getDockedDividerInsetsLw();
3397
3398 // If the divider is behind the navigation bar, don't animate.
Jorim Jaggi0cb0f722016-03-25 20:49:41 -07003399 final Rect frame = win.getFrameLw();
3400 final boolean behindNavBar = mNavigationBar != null
Adrian Roos85d202b2016-06-02 16:27:47 -07003401 && ((mNavigationBarPosition == NAV_BAR_BOTTOM
Jorim Jaggi0cb0f722016-03-25 20:49:41 -07003402 && frame.top + insets >= mNavigationBar.getFrameLw().top)
Adrian Roos85d202b2016-06-02 16:27:47 -07003403 || (mNavigationBarPosition == NAV_BAR_RIGHT
3404 && frame.left + insets >= mNavigationBar.getFrameLw().left)
3405 || (mNavigationBarPosition == NAV_BAR_LEFT
3406 && frame.right - insets <= mNavigationBar.getFrameLw().right));
Jorim Jaggi0cb0f722016-03-25 20:49:41 -07003407 final boolean landscape = frame.height() > frame.width();
3408 final boolean offscreenLandscape = landscape && (frame.right - insets <= 0
3409 || frame.left + insets >= win.getDisplayFrameLw().right);
3410 final boolean offscreenPortrait = !landscape && (frame.top - insets <= 0
3411 || frame.bottom + insets >= win.getDisplayFrameLw().bottom);
3412 final boolean offscreen = offscreenLandscape || offscreenPortrait;
3413 if (behindNavBar || offscreen) {
Jorim Jaggi81ba11e2016-02-03 22:04:22 -08003414 return 0;
3415 }
3416 if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
3417 return R.anim.fade_in;
3418 } else if (transit == TRANSIT_EXIT) {
3419 return R.anim.fade_out;
3420 } else {
3421 return 0;
3422 }
3423 }
3424
Craig Mautner3c174372013-02-21 17:54:37 -08003425 @Override
3426 public void selectRotationAnimationLw(int anim[]) {
Adrian Roos7c894802017-07-19 12:25:34 +02003427 // If the screen is off or non-interactive, force a jumpcut.
Adrian Roos3162b8f2017-07-25 15:37:32 +02003428 final boolean forceJumpcut = !mScreenOnFully || !okToAnimate();
Craig Mautner3c174372013-02-21 17:54:37 -08003429 if (PRINT_ANIM) Slog.i(TAG, "selectRotationAnimation mTopFullscreen="
3430 + mTopFullscreenOpaqueWindowState + " rotationAnimation="
3431 + (mTopFullscreenOpaqueWindowState == null ?
Adrian Roos7c894802017-07-19 12:25:34 +02003432 "0" : mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation)
3433 + " forceJumpcut=" + forceJumpcut);
3434 if (forceJumpcut) {
3435 anim[0] = R.anim.rotation_animation_jump_exit;
3436 anim[1] = R.anim.rotation_animation_enter;
3437 return;
3438 }
Robert Carrfd10cd12016-06-29 16:41:50 -07003439 if (mTopFullscreenOpaqueWindowState != null) {
3440 int animationHint = mTopFullscreenOpaqueWindowState.getRotationAnimationHint();
3441 if (animationHint < 0 && mTopIsFullscreen) {
3442 animationHint = mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation;
3443 }
3444 switch (animationHint) {
Craig Mautner3c174372013-02-21 17:54:37 -08003445 case ROTATION_ANIMATION_CROSSFADE:
Robert Carr57d9fbd2016-08-15 12:00:35 -07003446 case ROTATION_ANIMATION_SEAMLESS: // Crossfade is fallback for seamless.
Craig Mautner3c174372013-02-21 17:54:37 -08003447 anim[0] = R.anim.rotation_animation_xfade_exit;
3448 anim[1] = R.anim.rotation_animation_enter;
3449 break;
3450 case ROTATION_ANIMATION_JUMPCUT:
3451 anim[0] = R.anim.rotation_animation_jump_exit;
3452 anim[1] = R.anim.rotation_animation_enter;
3453 break;
3454 case ROTATION_ANIMATION_ROTATE:
3455 default:
3456 anim[0] = anim[1] = 0;
3457 break;
3458 }
3459 } else {
3460 anim[0] = anim[1] = 0;
3461 }
3462 }
3463
3464 @Override
3465 public boolean validateRotationAnimationLw(int exitAnimId, int enterAnimId,
3466 boolean forceDefault) {
3467 switch (exitAnimId) {
3468 case R.anim.rotation_animation_xfade_exit:
3469 case R.anim.rotation_animation_jump_exit:
3470 // These are the only cases that matter.
3471 if (forceDefault) {
3472 return false;
3473 }
3474 int anim[] = new int[2];
3475 selectRotationAnimationLw(anim);
3476 return (exitAnimId == anim[0] && enterAnimId == anim[1]);
3477 default:
3478 return true;
3479 }
3480 }
3481
3482 @Override
Jorim Jaggife762342016-10-13 14:33:27 +02003483 public Animation createHiddenByKeyguardExit(boolean onWallpaper,
Jorim Jaggi84a3e7a2014-08-13 17:58:58 +02003484 boolean goingToNotificationShade) {
3485 if (goingToNotificationShade) {
3486 return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_fade_in);
Craig Mautnerb8340802014-11-04 15:32:57 -08003487 }
Craig Mautner276a6eb2014-11-04 15:32:57 -08003488
3489 AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(mContext, onWallpaper ?
3490 R.anim.lock_screen_behind_enter_wallpaper :
3491 R.anim.lock_screen_behind_enter);
3492
3493 // TODO: Use XML interpolators when we have log interpolators available in XML.
3494 final List<Animation> animations = set.getAnimations();
3495 for (int i = animations.size() - 1; i >= 0; --i) {
3496 animations.get(i).setInterpolator(mLogDecelerateInterpolator);
3497 }
3498
3499 return set;
Jorim Jaggi76a16232014-08-08 17:00:47 +02003500 }
3501
3502
3503 @Override
Jorim Jaggife762342016-10-13 14:33:27 +02003504 public Animation createKeyguardWallpaperExit(boolean goingToNotificationShade) {
Jorim Jaggi84a3e7a2014-08-13 17:58:58 +02003505 if (goingToNotificationShade) {
3506 return null;
3507 } else {
3508 return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_wallpaper_exit);
3509 }
Dianne Hackborn01ad2f42009-09-24 19:24:56 -07003510 }
John Spurlockc8b46ca2013-04-08 12:59:26 -04003511
3512 private static void awakenDreams() {
3513 IDreamManager dreamManager = getDreamManager();
3514 if (dreamManager != null) {
3515 try {
3516 dreamManager.awaken();
3517 } catch (RemoteException e) {
3518 // fine, stay asleep then
3519 }
3520 }
3521 }
3522
3523 static IDreamManager getDreamManager() {
3524 return IDreamManager.Stub.asInterface(
3525 ServiceManager.checkService(DreamService.DREAM_SERVICE));
3526 }
3527
Tyler Gunnef9f6f92014-09-12 22:16:17 -07003528 TelecomManager getTelecommService() {
3529 return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003530 }
3531
Jeff Brown4d396052010-10-29 21:50:21 -07003532 static IAudioService getAudioService() {
3533 IAudioService audioService = IAudioService.Stub.asInterface(
3534 ServiceManager.checkService(Context.AUDIO_SERVICE));
3535 if (audioService == null) {
3536 Log.w(TAG, "Unable to find IAudioService interface.");
3537 }
3538 return audioService;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003539 }
3540
3541 boolean keyguardOn() {
Siarhei Vishniakou35fbb312017-12-13 13:48:50 -08003542 return isKeyguardShowingAndNotOccluded() || inKeyguardRestrictedKeyInputMode();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003543 }
3544
3545 private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = {
3546 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
3547 WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
3548 };
3549
3550 /** {@inheritDoc} */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003551 @Override
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003552 public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003553 final boolean keyguardOn = keyguardOn();
Jeff Brown1f245102010-11-18 20:53:46 -08003554 final int keyCode = event.getKeyCode();
3555 final int repeatCount = event.getRepeatCount();
3556 final int metaState = event.getMetaState();
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003557 final int flags = event.getFlags();
Jeff Brown1f245102010-11-18 20:53:46 -08003558 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
3559 final boolean canceled = event.isCanceled();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003560
Jeff Brown40013652012-05-16 21:22:36 -07003561 if (DEBUG_INPUT) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003562 Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
Jeff Brownfd23e3e2012-05-09 13:34:28 -07003563 + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed
3564 + " canceled=" + canceled);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003565 }
3566
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003567 // If we think we might have a volume down & power key chord on the way
3568 // but we're not sure, then tell the dispatcher to wait a little while and
3569 // try again later before dispatching.
Christopher Tatee90585f2012-03-05 18:56:25 -08003570 if (mScreenshotChordEnabled && (flags & KeyEvent.FLAG_FALLBACK) == 0) {
Jeff Brown13f00f02014-10-31 14:45:50 -07003571 if (mScreenshotChordVolumeDownKeyTriggered && !mScreenshotChordPowerKeyTriggered) {
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003572 final long now = SystemClock.uptimeMillis();
Jeff Brown13f00f02014-10-31 14:45:50 -07003573 final long timeoutTime = mScreenshotChordVolumeDownKeyTime
3574 + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003575 if (now < timeoutTime) {
3576 return timeoutTime - now;
3577 }
3578 }
3579 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
Jeff Brown13f00f02014-10-31 14:45:50 -07003580 && mScreenshotChordVolumeDownKeyConsumed) {
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003581 if (!down) {
Jeff Brown13f00f02014-10-31 14:45:50 -07003582 mScreenshotChordVolumeDownKeyConsumed = false;
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003583 }
3584 return -1;
3585 }
3586 }
3587
Phil Weaver106fe732016-11-22 18:18:39 -08003588 // If an accessibility shortcut might be partially complete, hold off dispatching until we
3589 // know if it is complete or not
Phil Weaverce687c52017-03-15 08:51:52 -07003590 if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(false)
Phil Weaver106fe732016-11-22 18:18:39 -08003591 && (flags & KeyEvent.FLAG_FALLBACK) == 0) {
3592 if (mScreenshotChordVolumeDownKeyTriggered ^ mA11yShortcutChordVolumeUpKeyTriggered) {
3593 final long now = SystemClock.uptimeMillis();
3594 final long timeoutTime = (mScreenshotChordVolumeDownKeyTriggered
3595 ? mScreenshotChordVolumeDownKeyTime : mA11yShortcutChordVolumeUpKeyTime)
3596 + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
3597 if (now < timeoutTime) {
3598 return timeoutTime - now;
3599 }
3600 }
3601 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN && mScreenshotChordVolumeDownKeyConsumed) {
3602 if (!down) {
3603 mScreenshotChordVolumeDownKeyConsumed = false;
3604 }
3605 return -1;
3606 }
3607 if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mA11yShortcutChordVolumeUpKeyConsumed) {
3608 if (!down) {
3609 mA11yShortcutChordVolumeUpKeyConsumed = false;
3610 }
3611 return -1;
3612 }
3613 }
3614
Mike Digman55272862018-02-20 14:35:17 -08003615 // If a ringer toggle chord could be on the way but we're not sure, then tell the dispatcher
3616 // to wait a little while and try again later before dispatching.
3617 if (mRingerToggleChord != VOLUME_HUSH_OFF && (flags & KeyEvent.FLAG_FALLBACK) == 0) {
3618 if (mA11yShortcutChordVolumeUpKeyTriggered && !mScreenshotChordPowerKeyTriggered) {
3619 final long now = SystemClock.uptimeMillis();
3620 final long timeoutTime = mA11yShortcutChordVolumeUpKeyTime
3621 + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
3622 if (now < timeoutTime) {
3623 return timeoutTime - now;
3624 }
3625 }
3626 if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mA11yShortcutChordVolumeUpKeyConsumed) {
3627 if (!down) {
3628 mA11yShortcutChordVolumeUpKeyConsumed = false;
3629 }
3630 return -1;
3631 }
3632 }
3633
Michael Wright6a62e552014-06-03 19:19:48 -07003634 // Cancel any pending meta actions if we see any other keys being pressed between the down
3635 // of the meta key and its corresponding up.
Michael Wright251e35d2014-08-22 15:40:27 -07003636 if (mPendingMetaAction && !KeyEvent.isMetaKey(keyCode)) {
Michael Wright6a62e552014-06-03 19:19:48 -07003637 mPendingMetaAction = false;
3638 }
Andrii Kulian112d0562016-03-08 10:44:22 -08003639 // Any key that is not Alt or Meta cancels Caps Lock combo tracking.
3640 if (mPendingCapsLockToggle && !KeyEvent.isMetaKey(keyCode) && !KeyEvent.isAltKey(keyCode)) {
3641 mPendingCapsLockToggle = false;
3642 }
Michael Wright6a62e552014-06-03 19:19:48 -07003643
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003644 // First we always handle the home key here, so applications
3645 // can never break it, although if keyguard is on, we do let
3646 // it handle it, because that gives us the correct 5 second
3647 // timeout.
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003648 if (keyCode == KeyEvent.KEYCODE_HOME) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07003649
Jeff Brown49ed71d2010-12-06 17:13:33 -08003650 // If we have released the home key, and didn't do anything else
3651 // while it was pressed, then it is time to go home!
Michael Jurka7f2668c2012-03-27 07:49:52 -07003652 if (!down) {
Jeff Browncaca8812013-05-09 13:34:33 -07003653 cancelPreloadRecentApps();
3654
Jeff Brown49ed71d2010-12-06 17:13:33 -08003655 mHomePressed = false;
Jeff Browncaca8812013-05-09 13:34:33 -07003656 if (mHomeConsumed) {
3657 mHomeConsumed = false;
Michael Jurka7f2668c2012-03-27 07:49:52 -07003658 return -1;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003659 }
Jeff Browncaca8812013-05-09 13:34:33 -07003660
3661 if (canceled) {
3662 Log.i(TAG, "Ignoring HOME; event canceled.");
3663 return -1;
3664 }
3665
Jeff Browncaca8812013-05-09 13:34:33 -07003666 // Delay handling home if a double-tap is possible.
3667 if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_NOTHING) {
3668 mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); // just in case
3669 mHomeDoubleTapPending = true;
3670 mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable,
3671 ViewConfiguration.getDoubleTapTimeout());
3672 return -1;
3673 }
3674
Jeff Brown13f00f02014-10-31 14:45:50 -07003675 handleShortPressOnHome();
Jeff Browncaca8812013-05-09 13:34:33 -07003676 return -1;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003677 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003678
3679 // If a system window has focus, then it doesn't make sense
3680 // right now to interact with applications.
3681 WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
3682 if (attrs != null) {
3683 final int type = attrs.type;
Jorim Jaggi73294b62016-10-26 18:02:36 -07003684 if (type == TYPE_KEYGUARD_DIALOG
Jorim Jaggi380ecb82014-03-14 17:25:20 +01003685 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003686 // the "app" is keyguard, so give it the key
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003687 return 0;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003688 }
3689 final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
3690 for (int i=0; i<typeCount; i++) {
3691 if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {
3692 // don't do anything, but also don't pass it to the app
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003693 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003694 }
3695 }
3696 }
Jeff Browncaca8812013-05-09 13:34:33 -07003697
3698 // Remember that home is pressed and handle special actions.
3699 if (repeatCount == 0) {
3700 mHomePressed = true;
3701 if (mHomeDoubleTapPending) {
3702 mHomeDoubleTapPending = false;
3703 mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable);
3704 handleDoubleTapOnHome();
Sid Soundararajanff662fa2017-03-15 16:24:24 -07003705 } else if (mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) {
Jeff Browncaca8812013-05-09 13:34:33 -07003706 preloadRecentApps();
Michael Jurka7f2668c2012-03-27 07:49:52 -07003707 }
Jeff Browncaca8812013-05-09 13:34:33 -07003708 } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
3709 if (!keyguardOn) {
Jaewan Kim76b7d0d2016-02-12 19:01:02 +09003710 handleLongPressOnHome(event.getDeviceId());
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003711 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003712 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003713 return -1;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003714 } else if (keyCode == KeyEvent.KEYCODE_MENU) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003715 // Hijack modified menu keys for debugging features
3716 final int chordBug = KeyEvent.META_SHIFT_ON;
3717
3718 if (down && repeatCount == 0) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003719 if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003720 Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07003721 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT,
3722 null, null, null, 0, null, null);
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003723 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003724 }
3725 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003726 } else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003727 if (down) {
3728 if (repeatCount == 0) {
Jeff Brownfd23e3e2012-05-09 13:34:28 -07003729 mSearchKeyShortcutPending = true;
3730 mConsumeSearchKeyUp = false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003731 }
Jeff Brownfd23e3e2012-05-09 13:34:28 -07003732 } else {
3733 mSearchKeyShortcutPending = false;
3734 if (mConsumeSearchKeyUp) {
3735 mConsumeSearchKeyUp = false;
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003736 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003737 }
3738 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003739 return 0;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003740 } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
Michael Wrightc9ebea72013-01-16 19:25:02 -08003741 if (!keyguardOn) {
Jeff Browncaca8812013-05-09 13:34:33 -07003742 if (down && repeatCount == 0) {
3743 preloadRecentApps();
3744 } else if (!down) {
3745 toggleRecentApps();
Michael Wrightc9ebea72013-01-16 19:25:02 -08003746 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08003747 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003748 return -1;
Jun Mukaid21b3c82015-04-23 14:09:34 -07003749 } else if (keyCode == KeyEvent.KEYCODE_N && event.isMetaPressed()) {
3750 if (down) {
3751 IStatusBarService service = getStatusBarService();
3752 if (service != null) {
3753 try {
3754 service.expandNotificationsPanel();
3755 } catch (RemoteException e) {
3756 // do nothing.
3757 }
3758 }
3759 }
Muyuan Li6ca619f2016-03-08 13:30:42 -08003760 } else if (keyCode == KeyEvent.KEYCODE_S && event.isMetaPressed()
3761 && event.isCtrlPressed()) {
3762 if (down && repeatCount == 0) {
3763 int type = event.isShiftPressed() ? TAKE_SCREENSHOT_SELECTED_REGION
3764 : TAKE_SCREENSHOT_FULLSCREEN;
3765 mScreenshotRunnable.setScreenshotType(type);
3766 mHandler.post(mScreenshotRunnable);
3767 return -1;
3768 }
Clara Bayarrif2debb12015-07-10 14:47:17 +01003769 } else if (keyCode == KeyEvent.KEYCODE_SLASH && event.isMetaPressed()) {
Andrei Stingaceanu002f7122016-03-30 12:22:05 +01003770 if (down && repeatCount == 0 && !isKeyguardLocked()) {
3771 toggleKeyboardShortcutsMenu(event.getDeviceId());
Clara Bayarrif2debb12015-07-10 14:47:17 +01003772 }
Jeff Brownde7a8ea2012-06-13 18:28:57 -07003773 } else if (keyCode == KeyEvent.KEYCODE_ASSIST) {
Siarhei Vishniakou191cf1b2017-08-17 16:17:22 -07003774 Slog.wtf(TAG, "KEYCODE_ASSIST should be handled in interceptKeyBeforeQueueing");
Jeff Brownde7a8ea2012-06-13 18:28:57 -07003775 return -1;
Michael Wrightdc63f7b2014-08-21 19:05:21 -07003776 } else if (keyCode == KeyEvent.KEYCODE_VOICE_ASSIST) {
Siarhei Vishniakou191cf1b2017-08-17 16:17:22 -07003777 Slog.wtf(TAG, "KEYCODE_VOICE_ASSIST should be handled in interceptKeyBeforeQueueing");
3778 return -1;
Jeff Sharkey2991fa32012-12-05 18:06:43 -08003779 } else if (keyCode == KeyEvent.KEYCODE_SYSRQ) {
3780 if (down && repeatCount == 0) {
Muyuan Li6ca619f2016-03-08 13:30:42 -08003781 mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN);
Jeff Sharkey2991fa32012-12-05 18:06:43 -08003782 mHandler.post(mScreenshotRunnable);
3783 }
3784 return -1;
Michael Wrightb854e242013-02-05 17:54:02 -08003785 } else if (keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP
3786 || keyCode == KeyEvent.KEYCODE_BRIGHTNESS_DOWN) {
3787 if (down) {
3788 int direction = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP ? 1 : -1;
3789
3790 // Disable autobrightness if it's on
3791 int auto = Settings.System.getIntForUser(
3792 mContext.getContentResolver(),
3793 Settings.System.SCREEN_BRIGHTNESS_MODE,
3794 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
3795 UserHandle.USER_CURRENT_OR_SELF);
3796 if (auto != 0) {
3797 Settings.System.putIntForUser(mContext.getContentResolver(),
3798 Settings.System.SCREEN_BRIGHTNESS_MODE,
3799 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
3800 UserHandle.USER_CURRENT_OR_SELF);
3801 }
3802
3803 int min = mPowerManager.getMinimumScreenBrightnessSetting();
3804 int max = mPowerManager.getMaximumScreenBrightnessSetting();
3805 int step = (max - min + BRIGHTNESS_STEPS - 1) / BRIGHTNESS_STEPS * direction;
3806 int brightness = Settings.System.getIntForUser(mContext.getContentResolver(),
3807 Settings.System.SCREEN_BRIGHTNESS,
3808 mPowerManager.getDefaultScreenBrightnessSetting(),
3809 UserHandle.USER_CURRENT_OR_SELF);
3810 brightness += step;
3811 // Make sure we don't go beyond the limits.
3812 brightness = Math.min(max, brightness);
3813 brightness = Math.max(min, brightness);
3814
3815 Settings.System.putIntForUser(mContext.getContentResolver(),
3816 Settings.System.SCREEN_BRIGHTNESS, brightness,
3817 UserHandle.USER_CURRENT_OR_SELF);
Bart Sears8b1c27c2015-03-18 23:51:02 +00003818 startActivityAsUser(new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG),
Alan Viverette5a399492014-07-14 16:19:38 -07003819 UserHandle.CURRENT_OR_SELF);
Michael Wrightb854e242013-02-05 17:54:02 -08003820 }
3821 return -1;
Jaewan Kim765487f2016-01-12 14:45:42 +09003822 } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP
3823 || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
3824 || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
Karthik Ravi Shankar86ecf342017-04-28 15:35:58 -07003825 if (mUseTvRouting || mHandleVolumeKeysInWM) {
3826 // On TVs or when the configuration is enabled, volume keys never
3827 // go to the foreground app.
Jaewan Kim765487f2016-01-12 14:45:42 +09003828 dispatchDirectAudioEvent(event);
3829 return -1;
3830 }
Karthik Ravi Shankar86ecf342017-04-28 15:35:58 -07003831
Michael Wright0a7e2ea72017-09-05 15:54:13 +01003832 // If the device is in VR mode and keys are "internal" (e.g. on the side of the
3833 // device), then drop the volume keys and don't forward it to the application/dispatch
3834 // the audio event.
Karthik Ravi Shankar86ecf342017-04-28 15:35:58 -07003835 if (mPersistentVrModeEnabled) {
Michael Wright0a7e2ea72017-09-05 15:54:13 +01003836 final InputDevice d = event.getDevice();
3837 if (d != null && !d.isExternal()) {
3838 return -1;
3839 }
Karthik Ravi Shankar86ecf342017-04-28 15:35:58 -07003840 }
Evan Rosky516f9e62017-01-23 16:43:52 -08003841 } else if (keyCode == KeyEvent.KEYCODE_TAB && event.isMetaPressed()) {
3842 // Pass through keyboard navigation keys.
3843 return 0;
Dmitri Plotnikov82e6dfc2017-02-24 18:10:54 -08003844 } else if (mHasFeatureLeanback && interceptBugreportGestureTv(keyCode, down)) {
3845 return -1;
Zhen Sun62e54c22017-08-17 15:56:20 -07003846 } else if (mHasFeatureLeanback && interceptAccessibilityGestureTv(keyCode, down)) {
3847 return -1;
Sujith Ramakrishnanf8942c02017-07-18 18:35:14 -07003848 } else if (keyCode == KeyEvent.KEYCODE_ALL_APPS) {
3849 if (!down) {
3850 mHandler.removeMessages(MSG_HANDLE_ALL_APPS);
3851 Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS);
3852 msg.setAsynchronous(true);
3853 msg.sendToTarget();
3854 }
3855 return -1;
Muyuan Li94ce94e2016-02-24 16:20:54 -08003856 }
3857
Andrii Kulian112d0562016-03-08 10:44:22 -08003858 // Toggle Caps Lock on META-ALT.
3859 boolean actionTriggered = false;
3860 if (KeyEvent.isModifierKey(keyCode)) {
3861 if (!mPendingCapsLockToggle) {
3862 // Start tracking meta state for combo.
3863 mInitialMetaState = mMetaState;
3864 mPendingCapsLockToggle = true;
3865 } else if (event.getAction() == KeyEvent.ACTION_UP) {
3866 int altOnMask = mMetaState & KeyEvent.META_ALT_MASK;
3867 int metaOnMask = mMetaState & KeyEvent.META_META_MASK;
3868
3869 // Check for Caps Lock toggle
3870 if ((metaOnMask != 0) && (altOnMask != 0)) {
3871 // Check if nothing else is pressed
3872 if (mInitialMetaState == (mMetaState ^ (altOnMask | metaOnMask))) {
3873 // Handle Caps Lock Toggle
3874 mInputManagerInternal.toggleCapsLock(event.getDeviceId());
3875 actionTriggered = true;
3876 }
3877 }
3878
3879 // Always stop tracking when key goes up.
3880 mPendingCapsLockToggle = false;
3881 }
3882 }
3883 // Store current meta state to be able to evaluate it later.
3884 mMetaState = metaState;
3885
3886 if (actionTriggered) {
3887 return -1;
3888 }
3889
Muyuan Li94ce94e2016-02-24 16:20:54 -08003890 if (KeyEvent.isMetaKey(keyCode)) {
Michael Wright6a62e552014-06-03 19:19:48 -07003891 if (down) {
3892 mPendingMetaAction = true;
3893 } else if (mPendingMetaAction) {
Tim Kilbourn0e5f1102015-06-05 16:18:09 -07003894 launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD, event.getDeviceId());
Michael Wright6a62e552014-06-03 19:19:48 -07003895 }
3896 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003897 }
Jeff Browncaab4d02010-12-09 22:13:41 -08003898
Jeff Brownc1fb48d2010-12-08 16:52:09 -08003899 // Shortcuts are invoked through Search+key, so intercept those here
Jeff Browncaab4d02010-12-09 22:13:41 -08003900 // Any printing key that is chorded with Search should be consumed
3901 // even if no shortcut was invoked. This prevents text from being
3902 // inadvertently inserted when using a keyboard that has built-in macro
3903 // shortcut keys (that emit Search+x) and some of them are not registered.
Jeff Brownfd23e3e2012-05-09 13:34:28 -07003904 if (mSearchKeyShortcutPending) {
Jeff Browncaab4d02010-12-09 22:13:41 -08003905 final KeyCharacterMap kcm = event.getKeyCharacterMap();
3906 if (kcm.isPrintingKey(keyCode)) {
Jeff Brownfd23e3e2012-05-09 13:34:28 -07003907 mConsumeSearchKeyUp = true;
3908 mSearchKeyShortcutPending = false;
Jeff Browncaab4d02010-12-09 22:13:41 -08003909 if (down && repeatCount == 0 && !keyguardOn) {
3910 Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, metaState);
3911 if (shortcutIntent != null) {
3912 shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Jeff Brownf0a3cc52011-01-26 18:42:46 -08003913 try {
Bart Sears8b1c27c2015-03-18 23:51:02 +00003914 startActivityAsUser(shortcutIntent, UserHandle.CURRENT);
Andrei Stingaceanu0bf096f2016-04-14 18:11:57 +01003915 dismissKeyboardShortcutsMenu();
Jeff Brownf0a3cc52011-01-26 18:42:46 -08003916 } catch (ActivityNotFoundException ex) {
3917 Slog.w(TAG, "Dropping shortcut key combination because "
3918 + "the activity to which it is registered was not found: "
Jeff Brownfd23e3e2012-05-09 13:34:28 -07003919 + "SEARCH+" + KeyEvent.keyCodeToString(keyCode), ex);
Jeff Brownf0a3cc52011-01-26 18:42:46 -08003920 }
Jeff Browncaab4d02010-12-09 22:13:41 -08003921 } else {
3922 Slog.i(TAG, "Dropping unregistered shortcut key combination: "
Jeff Brownfd23e3e2012-05-09 13:34:28 -07003923 + "SEARCH+" + KeyEvent.keyCodeToString(keyCode));
Jeff Brown49ed71d2010-12-06 17:13:33 -08003924 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003925 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003926 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003927 }
3928 }
3929
Jeff Brown68b909d2011-12-07 16:36:01 -08003930 // Invoke shortcuts using Meta.
Jeff Brown602ab322012-05-16 13:33:47 -07003931 if (down && repeatCount == 0 && !keyguardOn
Jeff Brown68b909d2011-12-07 16:36:01 -08003932 && (metaState & KeyEvent.META_META_ON) != 0) {
3933 final KeyCharacterMap kcm = event.getKeyCharacterMap();
Jeff Brown602ab322012-05-16 13:33:47 -07003934 if (kcm.isPrintingKey(keyCode)) {
3935 Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode,
3936 metaState & ~(KeyEvent.META_META_ON
3937 | KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON));
3938 if (shortcutIntent != null) {
3939 shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3940 try {
Bart Sears8b1c27c2015-03-18 23:51:02 +00003941 startActivityAsUser(shortcutIntent, UserHandle.CURRENT);
Andrei Stingaceanu0bf096f2016-04-14 18:11:57 +01003942 dismissKeyboardShortcutsMenu();
Jeff Brown602ab322012-05-16 13:33:47 -07003943 } catch (ActivityNotFoundException ex) {
3944 Slog.w(TAG, "Dropping shortcut key combination because "
3945 + "the activity to which it is registered was not found: "
3946 + "META+" + KeyEvent.keyCodeToString(keyCode), ex);
3947 }
3948 return -1;
Jeff Brown68b909d2011-12-07 16:36:01 -08003949 }
Jeff Brown68b909d2011-12-07 16:36:01 -08003950 }
3951 }
3952
Jeff Brown6651a632011-11-28 12:59:11 -08003953 // Handle application launch keys.
Jeff Brown602ab322012-05-16 13:33:47 -07003954 if (down && repeatCount == 0 && !keyguardOn) {
Jeff Brown6651a632011-11-28 12:59:11 -08003955 String category = sApplicationLaunchKeyCategories.get(keyCode);
3956 if (category != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -08003957 Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
Jeff Brown6651a632011-11-28 12:59:11 -08003958 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3959 try {
Bart Sears8b1c27c2015-03-18 23:51:02 +00003960 startActivityAsUser(intent, UserHandle.CURRENT);
Andrei Stingaceanu0bf096f2016-04-14 18:11:57 +01003961 dismissKeyboardShortcutsMenu();
Jeff Brown6651a632011-11-28 12:59:11 -08003962 } catch (ActivityNotFoundException ex) {
3963 Slog.w(TAG, "Dropping application launch key because "
3964 + "the activity to which it is registered was not found: "
3965 + "keyCode=" + keyCode + ", category=" + category, ex);
3966 }
Jeff Brown68b909d2011-12-07 16:36:01 -08003967 return -1;
Jeff Brown6651a632011-11-28 12:59:11 -08003968 }
3969 }
3970
Michael Wright61c46752014-08-21 16:57:33 -07003971 // Display task switcher for ALT-TAB.
Jeff Brown68b909d2011-12-07 16:36:01 -08003972 if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) {
Michael Wrightd847ad52015-10-24 13:24:15 +01003973 if (mRecentAppsHeldModifiers == 0 && !keyguardOn && isUserSetupComplete()) {
Jeff Brown68b909d2011-12-07 16:36:01 -08003974 final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
Michael Wright61c46752014-08-21 16:57:33 -07003975 if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)) {
Winson Chung1e8d71b2014-05-16 17:05:22 -07003976 mRecentAppsHeldModifiers = shiftlessModifiers;
Winson Chungdff7a732017-12-11 12:17:06 -08003977 showRecentApps(true);
Jeff Brown68b909d2011-12-07 16:36:01 -08003978 return -1;
3979 }
3980 }
Winson Chung1e8d71b2014-05-16 17:05:22 -07003981 } else if (!down && mRecentAppsHeldModifiers != 0
3982 && (metaState & mRecentAppsHeldModifiers) == 0) {
3983 mRecentAppsHeldModifiers = 0;
Winson Chungcdcd4872014-08-05 18:00:13 -07003984 hideRecentApps(true, false);
Jeff Brown68b909d2011-12-07 16:36:01 -08003985 }
3986
Yohei Yukawa2d9accb2018-03-07 19:15:15 -08003987 // Handle keyboard layout switching.
3988 // TODO: Deprecate this behavior when we fully migrate to IME subtype-based layout rotation.
3989 if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_SPACE
3990 && ((metaState & KeyEvent.META_CTRL_MASK) != 0)) {
3991 int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
3992 mWindowManagerFuncs.switchKeyboardLayout(event.getDeviceId(), direction);
3993 return -1;
3994 }
3995
Yohei Yukawaae61f712015-12-09 13:00:10 -08003996 // Handle input method switching.
Jeff Browncf39bdf2012-05-18 14:41:19 -07003997 if (down && repeatCount == 0
3998 && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH
3999 || (keyCode == KeyEvent.KEYCODE_SPACE
Yohei Yukawaae61f712015-12-09 13:00:10 -08004000 && (metaState & KeyEvent.META_META_MASK) != 0))) {
4001 final boolean forwardDirection = (metaState & KeyEvent.META_SHIFT_MASK) == 0;
4002 mWindowManagerFuncs.switchInputMethod(forwardDirection);
Jeff Browncf39bdf2012-05-18 14:41:19 -07004003 return -1;
4004 }
4005 if (mLanguageSwitchKeyPressed && !down
4006 && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH
4007 || keyCode == KeyEvent.KEYCODE_SPACE)) {
4008 mLanguageSwitchKeyPressed = false;
4009 return -1;
4010 }
4011
Jeff Brown13f00f02014-10-31 14:45:50 -07004012 if (isValidGlobalKey(keyCode)
4013 && mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
Justin Kohd378ad72013-04-01 12:18:26 -07004014 return -1;
4015 }
4016
Muyuan Li94ce94e2016-02-24 16:20:54 -08004017 if (down) {
Jim Millere4044bb2016-05-10 18:38:25 -07004018 long shortcutCode = keyCode;
Muyuan Li94ce94e2016-02-24 16:20:54 -08004019 if (event.isCtrlPressed()) {
4020 shortcutCode |= ((long) KeyEvent.META_CTRL_ON) << Integer.SIZE;
4021 }
4022
4023 if (event.isAltPressed()) {
4024 shortcutCode |= ((long) KeyEvent.META_ALT_ON) << Integer.SIZE;
4025 }
4026
4027 if (event.isShiftPressed()) {
4028 shortcutCode |= ((long) KeyEvent.META_SHIFT_ON) << Integer.SIZE;
4029 }
4030
4031 if (event.isMetaPressed()) {
4032 shortcutCode |= ((long) KeyEvent.META_META_ON) << Integer.SIZE;
4033 }
4034
4035 IShortcutService shortcutService = mShortcutKeyServices.get(shortcutCode);
4036 if (shortcutService != null) {
4037 try {
Muyuan Lib5dd0492016-04-14 13:22:20 -07004038 if (isUserSetupComplete()) {
4039 shortcutService.notifyShortcutKeyPressed(shortcutCode);
4040 }
Muyuan Li94ce94e2016-02-24 16:20:54 -08004041 } catch (RemoteException e) {
4042 mShortcutKeyServices.delete(shortcutCode);
4043 }
4044 return -1;
4045 }
4046 }
4047
Michael Wright6a62e552014-06-03 19:19:48 -07004048 // Reserve all the META modifier combos for system behavior
Michael Wrightce0c13a2014-07-30 10:49:21 -07004049 if ((metaState & KeyEvent.META_META_ON) != 0) {
Michael Wright6a62e552014-06-03 19:19:48 -07004050 return -1;
4051 }
4052
Jeff Brown68b909d2011-12-07 16:36:01 -08004053 // Let the application handle the key.
Jeff Brownd5bb82d2011-10-12 13:57:59 -07004054 return 0;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004055 }
4056
Dmitri Plotnikov82e6dfc2017-02-24 18:10:54 -08004057 /**
4058 * TV only: recognizes a remote control gesture for capturing a bug report.
4059 */
4060 private boolean interceptBugreportGestureTv(int keyCode, boolean down) {
4061 // The bugreport capture chord is a long press on DPAD CENTER and BACK simultaneously.
4062 if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
4063 mBugreportTvKey1Pressed = down;
4064 } else if (keyCode == KeyEvent.KEYCODE_BACK) {
4065 mBugreportTvKey2Pressed = down;
4066 }
4067
4068 if (mBugreportTvKey1Pressed && mBugreportTvKey2Pressed) {
4069 if (!mBugreportTvScheduled) {
4070 mBugreportTvScheduled = true;
4071 Message msg = Message.obtain(mHandler, MSG_BUGREPORT_TV);
4072 msg.setAsynchronous(true);
4073 mHandler.sendMessageDelayed(msg, BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS);
4074 }
4075 } else if (mBugreportTvScheduled) {
4076 mHandler.removeMessages(MSG_BUGREPORT_TV);
4077 mBugreportTvScheduled = false;
4078 }
4079
4080 return mBugreportTvScheduled;
4081 }
4082
Sujith Ramakrishnan6bed9bd2017-04-26 12:33:37 -07004083 /**
4084 * TV only: recognizes a remote control gesture as Accessibility shortcut.
Zhen Sun62e54c22017-08-17 15:56:20 -07004085 * Shortcut: Long press (BACK + DPAD_DOWN)
Sujith Ramakrishnan6bed9bd2017-04-26 12:33:37 -07004086 */
Zhen Sun62e54c22017-08-17 15:56:20 -07004087 private boolean interceptAccessibilityGestureTv(int keyCode, boolean down) {
4088 if (keyCode == KeyEvent.KEYCODE_BACK) {
4089 mAccessibilityTvKey1Pressed = down;
4090 } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
4091 mAccessibilityTvKey2Pressed = down;
4092 }
4093
Sujith Ramakrishnan6bed9bd2017-04-26 12:33:37 -07004094 if (mAccessibilityTvKey1Pressed && mAccessibilityTvKey2Pressed) {
4095 if (!mAccessibilityTvScheduled) {
4096 mAccessibilityTvScheduled = true;
4097 Message msg = Message.obtain(mHandler, MSG_ACCESSIBILITY_TV);
4098 msg.setAsynchronous(true);
Eugene Susla5f19cd32017-10-19 14:00:59 -07004099 mHandler.sendMessageDelayed(msg, getAccessibilityShortcutTimeout());
Sujith Ramakrishnan6bed9bd2017-04-26 12:33:37 -07004100 }
4101 } else if (mAccessibilityTvScheduled) {
4102 mHandler.removeMessages(MSG_ACCESSIBILITY_TV);
4103 mAccessibilityTvScheduled = false;
4104 }
Zhen Sun62e54c22017-08-17 15:56:20 -07004105
Sujith Ramakrishnan6bed9bd2017-04-26 12:33:37 -07004106 return mAccessibilityTvScheduled;
4107 }
4108
Dmitri Plotnikov82e6dfc2017-02-24 18:10:54 -08004109 private void takeBugreport() {
4110 if ("1".equals(SystemProperties.get("ro.debuggable"))
4111 || Settings.Global.getInt(mContext.getContentResolver(),
4112 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1) {
4113 try {
4114 ActivityManager.getService()
4115 .requestBugReport(ActivityManager.BUGREPORT_OPTION_INTERACTIVE);
4116 } catch (RemoteException e) {
4117 Slog.e(TAG, "Error taking bugreport", e);
4118 }
4119 }
4120 }
4121
Jeff Brown3915bb82010-11-05 15:02:16 -07004122 /** {@inheritDoc} */
4123 @Override
Jeff Brown49ed71d2010-12-06 17:13:33 -08004124 public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
Jeff Brown54875002011-04-06 15:33:01 -07004125 // Note: This method is only called if the initial down was unhandled.
Jeff Brown40013652012-05-16 21:22:36 -07004126 if (DEBUG_INPUT) {
Jeff Brown1f245102010-11-18 20:53:46 -08004127 Slog.d(TAG, "Unhandled key: win=" + win + ", action=" + event.getAction()
4128 + ", flags=" + event.getFlags()
4129 + ", keyCode=" + event.getKeyCode()
4130 + ", scanCode=" + event.getScanCode()
4131 + ", metaState=" + event.getMetaState()
4132 + ", repeatCount=" + event.getRepeatCount()
4133 + ", policyFlags=" + policyFlags);
Jeff Brown3915bb82010-11-05 15:02:16 -07004134 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08004135
Jeff Brownfd23e3e2012-05-09 13:34:28 -07004136 KeyEvent fallbackEvent = null;
Jeff Brown49ed71d2010-12-06 17:13:33 -08004137 if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
4138 final KeyCharacterMap kcm = event.getKeyCharacterMap();
Jeff Brownc1fb48d2010-12-08 16:52:09 -08004139 final int keyCode = event.getKeyCode();
4140 final int metaState = event.getMetaState();
Jeff Brownfd23e3e2012-05-09 13:34:28 -07004141 final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN
4142 && event.getRepeatCount() == 0;
Jeff Brown49ed71d2010-12-06 17:13:33 -08004143
Jeff Brown54875002011-04-06 15:33:01 -07004144 // Check for fallback actions specified by the key character map.
Jeff Brownfd23e3e2012-05-09 13:34:28 -07004145 final FallbackAction fallbackAction;
4146 if (initialDown) {
4147 fallbackAction = kcm.getFallbackAction(keyCode, metaState);
4148 } else {
4149 fallbackAction = mFallbackActions.get(keyCode);
4150 }
4151
4152 if (fallbackAction != null) {
Jeff Brown40013652012-05-16 21:22:36 -07004153 if (DEBUG_INPUT) {
Jeff Brownfd23e3e2012-05-09 13:34:28 -07004154 Slog.d(TAG, "Fallback: keyCode=" + fallbackAction.keyCode
4155 + " metaState=" + Integer.toHexString(fallbackAction.metaState));
Jeff Brown49ed71d2010-12-06 17:13:33 -08004156 }
4157
Jeff Brownfd23e3e2012-05-09 13:34:28 -07004158 final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
4159 fallbackEvent = KeyEvent.obtain(
Jeff Brown49ed71d2010-12-06 17:13:33 -08004160 event.getDownTime(), event.getEventTime(),
Jeff Brownfd23e3e2012-05-09 13:34:28 -07004161 event.getAction(), fallbackAction.keyCode,
4162 event.getRepeatCount(), fallbackAction.metaState,
Jeff Brown49ed71d2010-12-06 17:13:33 -08004163 event.getDeviceId(), event.getScanCode(),
4164 flags, event.getSource(), null);
Jeff Brownfd23e3e2012-05-09 13:34:28 -07004165
4166 if (!interceptFallback(win, fallbackEvent, policyFlags)) {
4167 fallbackEvent.recycle();
4168 fallbackEvent = null;
Jeff Brown49ed71d2010-12-06 17:13:33 -08004169 }
Jeff Brownfd23e3e2012-05-09 13:34:28 -07004170
4171 if (initialDown) {
4172 mFallbackActions.put(keyCode, fallbackAction);
4173 } else if (event.getAction() == KeyEvent.ACTION_UP) {
4174 mFallbackActions.remove(keyCode);
4175 fallbackAction.recycle();
4176 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08004177 }
4178 }
4179
Jeff Brown40013652012-05-16 21:22:36 -07004180 if (DEBUG_INPUT) {
Jeff Brownfd23e3e2012-05-09 13:34:28 -07004181 if (fallbackEvent == null) {
4182 Slog.d(TAG, "No fallback.");
4183 } else {
4184 Slog.d(TAG, "Performing fallback: " + fallbackEvent);
4185 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08004186 }
Jeff Brownfd23e3e2012-05-09 13:34:28 -07004187 return fallbackEvent;
Jeff Brown3915bb82010-11-05 15:02:16 -07004188 }
4189
Jeff Brownfd23e3e2012-05-09 13:34:28 -07004190 private boolean interceptFallback(WindowState win, KeyEvent fallbackEvent, int policyFlags) {
Jeff Brown037c33e2014-04-09 00:31:55 -07004191 int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags);
Jeff Brownfd23e3e2012-05-09 13:34:28 -07004192 if ((actions & ACTION_PASS_TO_USER) != 0) {
4193 long delayMillis = interceptKeyBeforeDispatching(
4194 win, fallbackEvent, policyFlags);
4195 if (delayMillis == 0) {
4196 return true;
4197 }
4198 }
4199 return false;
Jeff Brown6f2fba42011-02-19 01:08:02 -08004200 }
4201
Jim Millere4044bb2016-05-10 18:38:25 -07004202 @Override
Muyuan Li94ce94e2016-02-24 16:20:54 -08004203 public void registerShortcutKey(long shortcutCode, IShortcutService shortcutService)
4204 throws RemoteException {
4205 synchronized (mLock) {
4206 IShortcutService service = mShortcutKeyServices.get(shortcutCode);
Muyuan Li24d24ac2016-03-03 21:15:02 -08004207 if (service != null && service.asBinder().pingBinder()) {
4208 throw new RemoteException("Key already exists.");
Muyuan Li94ce94e2016-02-24 16:20:54 -08004209 }
4210
4211 mShortcutKeyServices.put(shortcutCode, shortcutService);
4212 }
4213 }
4214
Adrian Roosd88eb262016-08-04 14:50:48 -07004215 @Override
Jorim Jaggife762342016-10-13 14:33:27 +02004216 public void onKeyguardOccludedChangedLw(boolean occluded) {
4217 if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
4218 mPendingKeyguardOccluded = occluded;
4219 mKeyguardOccludedChanged = true;
4220 } else {
Jorim Jaggi9ba2e102017-04-04 12:51:03 +02004221 setKeyguardOccludedLw(occluded, false /* force */);
Jorim Jaggife762342016-10-13 14:33:27 +02004222 }
4223 }
4224
Jorim Jaggif5f9e122017-10-24 18:21:09 +02004225 private int handleStartTransitionForKeyguardLw(int transit, long duration) {
Jorim Jaggife762342016-10-13 14:33:27 +02004226 if (mKeyguardOccludedChanged) {
4227 if (DEBUG_KEYGUARD) Slog.d(TAG, "transition/occluded changed occluded="
4228 + mPendingKeyguardOccluded);
4229 mKeyguardOccludedChanged = false;
Jorim Jaggi9ba2e102017-04-04 12:51:03 +02004230 if (setKeyguardOccludedLw(mPendingKeyguardOccluded, false /* force */)) {
Jorim Jaggife762342016-10-13 14:33:27 +02004231 return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_WALLPAPER;
4232 }
4233 }
4234 if (AppTransition.isKeyguardGoingAwayTransit(transit)) {
Jorim Jaggi8d786932016-10-26 19:08:36 -07004235 if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation");
Jorim Jaggif5f9e122017-10-24 18:21:09 +02004236 startKeyguardExitAnimation(SystemClock.uptimeMillis(), duration);
Jorim Jaggife762342016-10-13 14:33:27 +02004237 }
4238 return 0;
Adrian Roosd88eb262016-08-04 14:50:48 -07004239 }
4240
Jeff Brownde7a8ea2012-06-13 18:28:57 -07004241 private void launchAssistLongPressAction() {
4242 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
4243 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
4244
4245 // launch the search activity
4246 Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS);
4247 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4248 try {
RoboErik8a2cfc32014-05-16 11:19:38 -07004249 // TODO: This only stops the factory-installed search manager.
Jim Miller45308b12012-06-18 19:23:39 -07004250 // Need to formalize an API to handle others
Jeff Brownde7a8ea2012-06-13 18:28:57 -07004251 SearchManager searchManager = getSearchManager();
4252 if (searchManager != null) {
4253 searchManager.stopSearch();
4254 }
Bart Sears8b1c27c2015-03-18 23:51:02 +00004255 startActivityAsUser(intent, UserHandle.CURRENT);
Jeff Brownde7a8ea2012-06-13 18:28:57 -07004256 } catch (ActivityNotFoundException e) {
4257 Slog.w(TAG, "No activity to handle assist long press action.", e);
4258 }
4259 }
4260
Tim Kilbourn0e5f1102015-06-05 16:18:09 -07004261 private void launchAssistAction(String hint, int deviceId) {
Jeff Brownde7a8ea2012-06-13 18:28:57 -07004262 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
Maurice Lam39d13812015-07-23 20:49:20 -07004263 if (!isUserSetupComplete()) {
4264 // Disable opening assist window during setup
4265 return;
4266 }
Tim Kilbourn0e5f1102015-06-05 16:18:09 -07004267 Bundle args = null;
4268 if (deviceId > Integer.MIN_VALUE) {
4269 args = new Bundle();
4270 args.putInt(Intent.EXTRA_ASSIST_INPUT_DEVICE_ID, deviceId);
Jeff Brownde7a8ea2012-06-13 18:28:57 -07004271 }
Jorim Jaggi165ce062015-07-06 16:18:11 -07004272 if ((mContext.getResources().getConfiguration().uiMode
4273 & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) {
4274 // On TV, use legacy handling until assistants are implemented in the proper way.
4275 ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
4276 .launchLegacyAssist(hint, UserHandle.myUserId(), args);
4277 } else {
Adrian Roosf2efdd82016-04-15 17:43:18 -07004278 if (hint != null) {
4279 if (args == null) {
4280 args = new Bundle();
Jorim Jaggi165ce062015-07-06 16:18:11 -07004281 }
Adrian Roosf2efdd82016-04-15 17:43:18 -07004282 args.putBoolean(hint, true);
4283 }
4284 StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4285 if (statusbar != null) {
4286 statusbar.startAssist(args);
Jorim Jaggi165ce062015-07-06 16:18:11 -07004287 }
4288 }
Jeff Brownde7a8ea2012-06-13 18:28:57 -07004289 }
4290
Bart Sears8b1c27c2015-03-18 23:51:02 +00004291 private void startActivityAsUser(Intent intent, UserHandle handle) {
4292 if (isUserSetupComplete()) {
4293 mContext.startActivityAsUser(intent, handle);
4294 } else {
4295 Slog.i(TAG, "Not starting activity because user setup is in progress: " + intent);
4296 }
4297 }
4298
Jeff Brownde7a8ea2012-06-13 18:28:57 -07004299 private SearchManager getSearchManager() {
4300 if (mSearchManager == null) {
4301 mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
4302 }
4303 return mSearchManager;
4304 }
4305
Jeff Browncaca8812013-05-09 13:34:33 -07004306 private void preloadRecentApps() {
4307 mPreloadedRecentApps = true;
Adrian Roosf2efdd82016-04-15 17:43:18 -07004308 StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4309 if (statusbar != null) {
4310 statusbar.preloadRecentApps();
Jeff Browncaca8812013-05-09 13:34:33 -07004311 }
4312 }
4313
4314 private void cancelPreloadRecentApps() {
4315 if (mPreloadedRecentApps) {
4316 mPreloadedRecentApps = false;
Adrian Roosf2efdd82016-04-15 17:43:18 -07004317 StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4318 if (statusbar != null) {
4319 statusbar.cancelPreloadRecentApps();
Jeff Browncaca8812013-05-09 13:34:33 -07004320 }
4321 }
4322 }
4323
4324 private void toggleRecentApps() {
4325 mPreloadedRecentApps = false; // preloading no longer needs to be canceled
Adrian Roosf2efdd82016-04-15 17:43:18 -07004326 StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4327 if (statusbar != null) {
4328 statusbar.toggleRecentApps();
Winson Chung1e8d71b2014-05-16 17:05:22 -07004329 }
4330 }
4331
Craig Mautner84984fa2014-06-19 11:19:20 -07004332 @Override
Winson Chungdff7a732017-12-11 12:17:06 -08004333 public void showRecentApps() {
Craig Mautner84984fa2014-06-19 11:19:20 -07004334 mHandler.removeMessages(MSG_DISPATCH_SHOW_RECENTS);
Winson Chungdff7a732017-12-11 12:17:06 -08004335 mHandler.obtainMessage(MSG_DISPATCH_SHOW_RECENTS).sendToTarget();
Craig Mautner84984fa2014-06-19 11:19:20 -07004336 }
4337
Winson Chungdff7a732017-12-11 12:17:06 -08004338 private void showRecentApps(boolean triggeredFromAltTab) {
Winson Chung1e8d71b2014-05-16 17:05:22 -07004339 mPreloadedRecentApps = false; // preloading no longer needs to be canceled
Adrian Roosf2efdd82016-04-15 17:43:18 -07004340 StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4341 if (statusbar != null) {
Winson Chungdff7a732017-12-11 12:17:06 -08004342 statusbar.showRecentApps(triggeredFromAltTab);
Jeff Browncaca8812013-05-09 13:34:33 -07004343 }
4344 }
4345
Clara Bayarri4e850ff2016-03-02 11:12:32 -08004346 private void toggleKeyboardShortcutsMenu(int deviceId) {
Adrian Roosf2efdd82016-04-15 17:43:18 -07004347 StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4348 if (statusbar != null) {
4349 statusbar.toggleKeyboardShortcutsMenu(deviceId);
Clara Bayarrif2debb12015-07-10 14:47:17 +01004350 }
4351 }
4352
Andrei Stingaceanu0bf096f2016-04-14 18:11:57 +01004353 private void dismissKeyboardShortcutsMenu() {
4354 StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4355 if (statusbar != null) {
4356 statusbar.dismissKeyboardShortcutsMenu();
4357 }
4358 }
4359
Winson Chungcdcd4872014-08-05 18:00:13 -07004360 private void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHome) {
Winson Chung1e8d71b2014-05-16 17:05:22 -07004361 mPreloadedRecentApps = false; // preloading no longer needs to be canceled
Adrian Roosf2efdd82016-04-15 17:43:18 -07004362 StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4363 if (statusbar != null) {
4364 statusbar.hideRecentApps(triggeredFromAltTab, triggeredFromHome);
Winson Chung1e8d71b2014-05-16 17:05:22 -07004365 }
4366 }
4367
Filip Gruszczynskia483a1d2015-03-17 19:06:58 +00004368 void launchHomeFromHotKey() {
Bryce Lee662ed802015-04-10 20:11:39 +00004369 launchHomeFromHotKey(true /* awakenFromDreams */, true /*respectKeyguard*/);
Filip Gruszczynskia483a1d2015-03-17 19:06:58 +00004370 }
4371
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004372 /**
4373 * A home key -> launch home action was detected. Take the appropriate action
4374 * given the situation with the keyguard.
4375 */
Bryce Lee662ed802015-04-10 20:11:39 +00004376 void launchHomeFromHotKey(final boolean awakenFromDreams, final boolean respectKeyguard) {
Adrian Roos842e7882018-03-26 17:34:06 +02004377 // Abort possibly stuck animations.
4378 mHandler.post(mWindowManagerFuncs::triggerAnimationFailsafe);
4379
Bryce Lee662ed802015-04-10 20:11:39 +00004380 if (respectKeyguard) {
4381 if (isKeyguardShowingAndNotOccluded()) {
4382 // don't launch home if keyguard showing
4383 return;
Winson Chung2a35e6d2018-01-13 14:27:50 -08004384 } else if (mKeyguardOccluded && mKeyguardDelegate.isShowing()) {
4385 mKeyguardDelegate.dismiss(new KeyguardDismissCallback() {
4386 @Override
4387 public void onDismissSucceeded() throws RemoteException {
4388 mHandler.post(() -> {
4389 startDockOrHome(true /*fromHomeKey*/, awakenFromDreams);
4390 });
4391 }
4392 }, null /* message */);
4393 return;
4394 } else if (!mKeyguardOccluded && mKeyguardDelegate.isInputRestricted()) {
Bryce Lee662ed802015-04-10 20:11:39 +00004395 // when in keyguard restricted mode, must first verify unlock
4396 // before launching home
4397 mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() {
4398 @Override
4399 public void onKeyguardExitResult(boolean success) {
4400 if (success) {
Bryce Lee662ed802015-04-10 20:11:39 +00004401 startDockOrHome(true /*fromHomeKey*/, awakenFromDreams);
Dianne Hackborn256dd3b2009-05-19 18:51:21 -07004402 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004403 }
Bryce Lee662ed802015-04-10 20:11:39 +00004404 });
4405 return;
4406 }
4407 }
4408
4409 // no keyguard stuff to worry about, just launch home!
Bryce Lee662ed802015-04-10 20:11:39 +00004410 if (mRecentsVisible) {
Winson Chung2a35e6d2018-01-13 14:27:50 -08004411 try {
4412 ActivityManager.getService().stopAppSwitches();
4413 } catch (RemoteException e) {}
4414
Bryce Lee662ed802015-04-10 20:11:39 +00004415 // Hide Recents and notify it to launch Home
4416 if (awakenFromDreams) {
4417 awakenDreams();
4418 }
Bryce Lee662ed802015-04-10 20:11:39 +00004419 hideRecentApps(false, true);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004420 } else {
Bryce Lee662ed802015-04-10 20:11:39 +00004421 // Otherwise, just launch Home
Bryce Lee662ed802015-04-10 20:11:39 +00004422 startDockOrHome(true /*fromHomeKey*/, awakenFromDreams);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004423 }
4424 }
4425
John Spurlock04db1762013-05-13 12:46:41 -04004426 private final Runnable mClearHideNavigationFlag = new Runnable() {
4427 @Override
4428 public void run() {
4429 synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
4430 // Clear flags.
4431 mForceClearedSystemUiFlags &=
4432 ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
4433 }
4434 mWindowManagerFuncs.reevaluateStatusBarVisibility();
Dianne Hackborne26ab702011-10-16 13:21:33 -07004435 }
4436 };
4437
4438 /**
4439 * Input handler used while nav bar is hidden. Captures any touch on the screen,
4440 * to determine when the nav bar should be shown and prevent applications from
4441 * receiving those touches.
4442 */
Jeff Brown32cbc38552011-12-01 14:01:49 -08004443 final class HideNavInputEventReceiver extends InputEventReceiver {
4444 public HideNavInputEventReceiver(InputChannel inputChannel, Looper looper) {
4445 super(inputChannel, looper);
4446 }
4447
Dianne Hackborndf89e652011-10-06 22:35:11 -07004448 @Override
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -07004449 public void onInputEvent(InputEvent event, int displayId) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07004450 boolean handled = false;
4451 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -08004452 if (event instanceof MotionEvent
4453 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
4454 final MotionEvent motionEvent = (MotionEvent)event;
4455 if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07004456 // When the user taps down, we re-show the nav bar.
4457 boolean changed = false;
John Spurlock04db1762013-05-13 12:46:41 -04004458 synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
Chong Zhang9f7fb092016-05-20 17:03:08 -07004459 if (mInputConsumer == null) {
4460 return;
4461 }
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07004462 // Any user activity always causes us to show the
4463 // navigation controls, if they had been hidden.
4464 // We also clear the low profile and only content
4465 // flags so that tapping on the screen will atomically
4466 // restore all currently hidden screen decorations.
4467 int newVal = mResettingSystemUiFlags |
4468 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
4469 View.SYSTEM_UI_FLAG_LOW_PROFILE |
4470 View.SYSTEM_UI_FLAG_FULLSCREEN;
Dianne Hackborne26ab702011-10-16 13:21:33 -07004471 if (mResettingSystemUiFlags != newVal) {
4472 mResettingSystemUiFlags = newVal;
Dianne Hackborndf89e652011-10-06 22:35:11 -07004473 changed = true;
4474 }
Dianne Hackborne26ab702011-10-16 13:21:33 -07004475 // We don't allow the system's nav bar to be hidden
4476 // again for 1 second, to prevent applications from
4477 // spamming us and keeping it from being shown.
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07004478 newVal = mForceClearedSystemUiFlags |
4479 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
Dianne Hackborne26ab702011-10-16 13:21:33 -07004480 if (mForceClearedSystemUiFlags != newVal) {
4481 mForceClearedSystemUiFlags = newVal;
4482 changed = true;
John Spurlock04db1762013-05-13 12:46:41 -04004483 mHandler.postDelayed(mClearHideNavigationFlag, 1000);
Dianne Hackborne26ab702011-10-16 13:21:33 -07004484 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07004485 }
4486 if (changed) {
4487 mWindowManagerFuncs.reevaluateStatusBarVisibility();
4488 }
4489 }
4490 }
4491 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -08004492 finishInputEvent(event, handled);
Dianne Hackborndf89e652011-10-06 22:35:11 -07004493 }
4494 }
Jeff Brown32cbc38552011-12-01 14:01:49 -08004495 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07004496
4497 @Override
Winsonab216602016-08-09 14:05:20 -07004498 public void setRecentsVisibilityLw(boolean visible) {
4499 mRecentsVisible = visible;
4500 }
4501
4502 @Override
Winson Chungac52f282017-03-30 14:44:52 -07004503 public void setPipVisibilityLw(boolean visible) {
4504 mPictureInPictureVisible = visible;
Winsonab216602016-08-09 14:05:20 -07004505 }
4506
4507 @Override
Matthew Ng64543e62018-02-28 17:35:10 -08004508 public void setNavBarVirtualKeyHapticFeedbackEnabledLw(boolean enabled) {
4509 mNavBarVirtualKeyHapticFeedbackEnabled = enabled;
4510 }
4511
4512 @Override
Dianne Hackborndf89e652011-10-06 22:35:11 -07004513 public int adjustSystemUiVisibilityLw(int visibility) {
John Spurlock5b9145b2013-08-20 15:13:47 -04004514 mStatusBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility);
4515 mNavigationBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility);
John Spurlock27735a42013-08-14 17:57:38 -04004516
Dianne Hackborndf89e652011-10-06 22:35:11 -07004517 // Reset any bits in mForceClearingStatusBarVisibility that
4518 // are now clear.
Dianne Hackborne26ab702011-10-16 13:21:33 -07004519 mResettingSystemUiFlags &= visibility;
Dianne Hackborndf89e652011-10-06 22:35:11 -07004520 // Clear any bits in the new visibility that are currently being
4521 // force cleared, before reporting it.
Dianne Hackborne26ab702011-10-16 13:21:33 -07004522 return visibility & ~mResettingSystemUiFlags
4523 & ~mForceClearedSystemUiFlags;
Dianne Hackborndf89e652011-10-06 22:35:11 -07004524 }
4525
Craig Mautner69b08182012-09-05 13:07:13 -07004526 @Override
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004527 // TODO: Should probably be moved into DisplayFrames.
Adrian Roos9e370f22018-03-06 18:19:45 +01004528 public boolean getLayoutHintLw(WindowManager.LayoutParams attrs, Rect taskBounds,
4529 DisplayFrames displayFrames, Rect outFrame, Rect outContentInsets, Rect outStableInsets,
Adrian Roos5c6b6222017-11-07 17:36:10 +01004530 Rect outOutsets, DisplayCutout.ParcelableWrapper outDisplayCutout) {
John Spurlockc6d1c602014-01-17 15:22:06 -05004531 final int fl = PolicyControl.getWindowFlags(null, attrs);
Adrian Roosf8898ab2018-01-22 17:47:28 +01004532 final int pfl = attrs.privateFlags;
Adrian Roos9e370f22018-03-06 18:19:45 +01004533 final int requestedSysUiVis = PolicyControl.getSystemUiVisibility(null, attrs);
4534 final int sysUiVis = requestedSysUiVis | getImpliedSysUiFlagsForLayout(attrs);
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004535 final int displayRotation = displayFrames.mRotation;
4536 final int displayWidth = displayFrames.mDisplayWidth;
4537 final int displayHeight = displayFrames.mDisplayHeight;
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07004538
Filip Gruszczynski2987f612015-06-30 15:03:30 -07004539 final boolean useOutsets = outOutsets != null && shouldUseOutsets(attrs, fl);
4540 if (useOutsets) {
4541 int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources());
4542 if (outset > 0) {
4543 if (displayRotation == Surface.ROTATION_0) {
4544 outOutsets.bottom += outset;
4545 } else if (displayRotation == Surface.ROTATION_90) {
4546 outOutsets.right += outset;
4547 } else if (displayRotation == Surface.ROTATION_180) {
4548 outOutsets.top += outset;
4549 } else if (displayRotation == Surface.ROTATION_270) {
4550 outOutsets.left += outset;
4551 }
4552 }
4553 }
4554
Adrian Roos9e370f22018-03-06 18:19:45 +01004555 final boolean layoutInScreen = (fl & FLAG_LAYOUT_IN_SCREEN) != 0;
4556 final boolean layoutInScreenAndInsetDecor = layoutInScreen &&
4557 (fl & FLAG_LAYOUT_INSET_DECOR) != 0;
Adrian Roosf8898ab2018-01-22 17:47:28 +01004558 final boolean screenDecor = (pfl & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0;
4559
4560 if (layoutInScreenAndInsetDecor && !screenDecor) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07004561 int availRight, availBottom;
Alan Viverette5a0f4ec2013-10-07 15:10:29 -07004562 if (canHideNavigationBar() &&
Adrian Roos9e370f22018-03-06 18:19:45 +01004563 (sysUiVis & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) {
4564 outFrame.set(displayFrames.mUnrestricted);
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004565 availRight = displayFrames.mUnrestricted.right;
4566 availBottom = displayFrames.mUnrestricted.bottom;
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07004567 } else {
Adrian Roos9e370f22018-03-06 18:19:45 +01004568 outFrame.set(displayFrames.mRestricted);
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004569 availRight = displayFrames.mRestricted.right;
4570 availBottom = displayFrames.mRestricted.bottom;
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07004571 }
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004572 outStableInsets.set(displayFrames.mStable.left, displayFrames.mStable.top,
4573 availRight - displayFrames.mStable.right,
4574 availBottom - displayFrames.mStable.bottom);
4575
Adrian Roos9e370f22018-03-06 18:19:45 +01004576 if ((sysUiVis & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) {
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07004577 if ((fl & FLAG_FULLSCREEN) != 0) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004578 outContentInsets.set(displayFrames.mStableFullscreen.left,
4579 displayFrames.mStableFullscreen.top,
4580 availRight - displayFrames.mStableFullscreen.right,
4581 availBottom - displayFrames.mStableFullscreen.bottom);
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07004582 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004583 outContentInsets.set(outStableInsets);
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07004584 }
Dianne Hackbornc652de82013-02-15 16:32:56 -08004585 } else if ((fl & FLAG_FULLSCREEN) != 0 || (fl & FLAG_LAYOUT_IN_OVERSCAN) != 0) {
Adrian Roos37d7a682014-11-06 18:15:16 +01004586 outContentInsets.setEmpty();
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07004587 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004588 outContentInsets.set(displayFrames.mCurrent.left, displayFrames.mCurrent.top,
4589 availRight - displayFrames.mCurrent.right,
4590 availBottom - displayFrames.mCurrent.bottom);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07004591 }
Adrian Roos37d7a682014-11-06 18:15:16 +01004592
Jorim Jaggi23bf5462016-05-13 15:24:39 -07004593 if (taskBounds != null) {
4594 calculateRelevantTaskInsets(taskBounds, outContentInsets,
4595 displayWidth, displayHeight);
4596 calculateRelevantTaskInsets(taskBounds, outStableInsets,
4597 displayWidth, displayHeight);
Adrian Roos9e370f22018-03-06 18:19:45 +01004598 outFrame.intersect(taskBounds);
Jorim Jaggi23bf5462016-05-13 15:24:39 -07004599 }
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01004600 outDisplayCutout.set(displayFrames.mDisplayCutout.calculateRelativeTo(outFrame)
4601 .getDisplayCutout());
Adrian Roos9e370f22018-03-06 18:19:45 +01004602 return mForceShowSystemBars;
4603 } else {
4604 if (layoutInScreen) {
4605 outFrame.set(displayFrames.mUnrestricted);
4606 } else {
4607 outFrame.set(displayFrames.mStable);
4608 }
4609 if (taskBounds != null) {
4610 outFrame.intersect(taskBounds);
4611 }
4612
4613 outContentInsets.setEmpty();
4614 outStableInsets.setEmpty();
4615 outDisplayCutout.set(DisplayCutout.NO_CUTOUT);
Jorim Jaggi0ffd49c2016-02-12 15:04:21 -08004616 return mForceShowSystemBars;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004617 }
4618 }
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07004619
Jorim Jaggi23bf5462016-05-13 15:24:39 -07004620 /**
4621 * For any given task bounds, the insets relevant for these bounds given the insets relevant
4622 * for the entire display.
4623 */
4624 private void calculateRelevantTaskInsets(Rect taskBounds, Rect inOutInsets, int displayWidth,
4625 int displayHeight) {
4626 mTmpRect.set(0, 0, displayWidth, displayHeight);
4627 mTmpRect.inset(inOutInsets);
4628 mTmpRect.intersect(taskBounds);
4629 int leftInset = mTmpRect.left - taskBounds.left;
4630 int topInset = mTmpRect.top - taskBounds.top;
4631 int rightInset = taskBounds.right - mTmpRect.right;
4632 int bottomInset = taskBounds.bottom - mTmpRect.bottom;
4633 inOutInsets.set(leftInset, topInset, rightInset, bottomInset);
4634 }
4635
Filip Gruszczynski2987f612015-06-30 15:03:30 -07004636 private boolean shouldUseOutsets(WindowManager.LayoutParams attrs, int fl) {
4637 return attrs.type == TYPE_WALLPAPER || (fl & (WindowManager.LayoutParams.FLAG_FULLSCREEN
4638 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN)) != 0;
4639 }
4640
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004641 /** {@inheritDoc} */
Craig Mautner69b08182012-09-05 13:07:13 -07004642 @Override
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004643 public void beginLayoutLw(DisplayFrames displayFrames, int uiMode) {
Adrian Roos30f53212018-01-05 16:14:34 +01004644 displayFrames.onBeginLayout();
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004645 // TODO(multi-display): This doesn't seem right...Maybe only apply to default display?
4646 mSystemGestures.screenWidth = displayFrames.mUnrestricted.width();
4647 mSystemGestures.screenHeight = displayFrames.mUnrestricted.height();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004648 mDockLayer = 0x10000000;
Dianne Hackborn5c58de32012-04-28 19:52:37 -07004649 mStatusBarLayer = -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004650
Daniel Sandler8956dbb2011-04-22 07:55:02 -04004651 // start with the current dock rect, which will be (0,0,displayWidth,displayHeight)
4652 final Rect pf = mTmpParentFrame;
4653 final Rect df = mTmpDisplayFrame;
Dianne Hackbornc4aad012013-02-22 15:05:25 -08004654 final Rect of = mTmpOverscanFrame;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04004655 final Rect vf = mTmpVisibleFrame;
John Spurlock46646232013-09-30 22:32:42 -04004656 final Rect dcf = mTmpDecorFrame;
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004657 vf.set(displayFrames.mDock);
4658 of.set(displayFrames.mDock);
4659 df.set(displayFrames.mDock);
4660 pf.set(displayFrames.mDock);
John Spurlock46646232013-09-30 22:32:42 -04004661 dcf.setEmpty(); // Decor frame N/A for system bars.
Daniel Sandler8956dbb2011-04-22 07:55:02 -04004662
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004663 if (displayFrames.mDisplayId == DEFAULT_DISPLAY) {
Craig Mautner69b08182012-09-05 13:07:13 -07004664 // For purposes of putting out fake window up to steal focus, we will
4665 // drive nav being hidden only by whether it is requested.
John Spurlocke1f366f2013-08-05 12:22:40 -04004666 final int sysui = mLastSystemUiFlags;
4667 boolean navVisible = (sysui & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
Adrian Roosea562512014-05-05 13:33:03 +02004668 boolean navTranslucent = (sysui
Jorim Jaggi4fa78922015-11-30 17:13:56 -08004669 & (View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT)) != 0;
John Spurlockf1a36642013-10-12 17:50:42 -04004670 boolean immersive = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0;
4671 boolean immersiveSticky = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
4672 boolean navAllowedHidden = immersive || immersiveSticky;
4673 navTranslucent &= !immersiveSticky; // transient trumps translucent
Jorim Jaggife762342016-10-13 14:33:27 +02004674 boolean isKeyguardShowing = isStatusBarKeyguard() && !mKeyguardOccluded;
Adrian Roos4fb3ee32014-08-22 19:29:09 +02004675 if (!isKeyguardShowing) {
4676 navTranslucent &= areTranslucentBarsAllowed();
4677 }
Jaewan Kim33284332016-05-12 18:55:46 +09004678 boolean statusBarExpandedNotKeyguard = !isKeyguardShowing && mStatusBar != null
Adrian Roosdb1bc6b2016-04-14 17:49:43 -07004679 && mStatusBar.getAttrs().height == MATCH_PARENT
4680 && mStatusBar.getAttrs().width == MATCH_PARENT;
Dianne Hackborne26ab702011-10-16 13:21:33 -07004681
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004682 // When the navigation bar isn't visible, we put up a fake input window to catch all
4683 // touch events. This way we can detect when the user presses anywhere to bring back the
4684 // nav bar and ensure the application doesn't see the event.
John Spurlockf1a36642013-10-12 17:50:42 -04004685 if (navVisible || navAllowedHidden) {
Selim Cinekf83e8242015-05-19 18:08:14 -07004686 if (mInputConsumer != null) {
Chong Zhang9f7fb092016-05-20 17:03:08 -07004687 mHandler.sendMessage(
4688 mHandler.obtainMessage(MSG_DISPOSE_INPUT_CONSUMER, mInputConsumer));
Selim Cinekf83e8242015-05-19 18:08:14 -07004689 mInputConsumer = null;
Craig Mautner69b08182012-09-05 13:07:13 -07004690 }
Tun Zheng66dc0352018-01-15 16:55:06 +08004691 } else if (mInputConsumer == null && mStatusBar != null && canHideNavigationBar()) {
Winson41275482016-10-10 15:17:45 -07004692 mInputConsumer = mWindowManagerFuncs.createInputConsumer(mHandler.getLooper(),
4693 INPUT_CONSUMER_NAVIGATION,
4694 (channel, looper) -> new HideNavInputEventReceiver(channel, looper));
Vladislav Kaznacheev19dab2d2017-02-07 10:12:51 -08004695 // As long as mInputConsumer is active, hover events are not dispatched to the app
4696 // and the pointer icon is likely to become stale. Hide it to avoid confusion.
4697 InputManager.getInstance().setPointerIconType(PointerIcon.TYPE_NULL);
Dianne Hackborne26ab702011-10-16 13:21:33 -07004698 }
Dianne Hackborne26ab702011-10-16 13:21:33 -07004699
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004700 // For purposes of positioning and showing the nav bar, if we have decided that it can't
4701 // be hidden (because of the screen aspect ratio), then take that into account.
Alan Viverette5a0f4ec2013-10-07 15:10:29 -07004702 navVisible |= !canHideNavigationBar();
Dianne Hackbornf87d1962012-04-04 12:48:24 -07004703
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004704 boolean updateSysUiVisibility = layoutNavigationBar(displayFrames, uiMode, dcf,
4705 navVisible, navTranslucent, navAllowedHidden, statusBarExpandedNotKeyguard);
4706 if (DEBUG_LAYOUT) Slog.i(TAG, "mDock rect:" + displayFrames.mDock);
4707 updateSysUiVisibility |= layoutStatusBar(
4708 displayFrames, pf, df, of, vf, dcf, sysui, isKeyguardShowing);
John Spurlockad3e6cb2013-04-30 08:47:43 -04004709 if (updateSysUiVisibility) {
4710 updateSystemUiVisibilityLw();
4711 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004712 }
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004713 layoutScreenDecorWindows(displayFrames, pf, df, dcf);
Adrian Roosdcc92ed2017-11-22 14:35:58 +01004714
4715 if (displayFrames.mDisplayCutoutSafe.top > displayFrames.mUnrestricted.top) {
4716 // Make sure that the zone we're avoiding for the cutout is at least as tall as the
4717 // status bar; otherwise fullscreen apps will end up cutting halfway into the status
4718 // bar.
4719 displayFrames.mDisplayCutoutSafe.top = Math.max(displayFrames.mDisplayCutoutSafe.top,
4720 displayFrames.mStable.top);
4721 }
Wale Ogunwalec0b0f932017-11-01 12:51:43 -07004722 }
4723
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004724 private void layoutScreenDecorWindows(DisplayFrames displayFrames, Rect pf, Rect df, Rect dcf) {
Wale Ogunwalec0b0f932017-11-01 12:51:43 -07004725 if (mScreenDecorWindows.isEmpty()) {
4726 return;
4727 }
4728
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004729 final int displayId = displayFrames.mDisplayId;
4730 final Rect dockFrame = displayFrames.mDock;
4731 final int displayHeight = displayFrames.mDisplayHeight;
4732 final int displayWidth = displayFrames.mDisplayWidth;
4733
Wale Ogunwalec0b0f932017-11-01 12:51:43 -07004734 for (int i = mScreenDecorWindows.size() - 1; i >= 0; --i) {
4735 final WindowState w = mScreenDecorWindows.valueAt(i);
4736 if (w.getDisplayId() != displayId || !w.isVisibleLw()) {
4737 // Skip if not on the same display or not visible.
4738 continue;
4739 }
4740
4741 w.computeFrameLw(pf /* parentFrame */, df /* displayFrame */, df /* overlayFrame */,
4742 df /* contentFrame */, df /* visibleFrame */, dcf /* decorFrame */,
Adrian Roos5ed644f2018-03-19 17:01:05 +01004743 df /* stableFrame */, df /* outsetFrame */, displayFrames.mDisplayCutout,
4744 false /* parentFrameWasClippedByDisplayCutout */);
Wale Ogunwalec0b0f932017-11-01 12:51:43 -07004745 final Rect frame = w.getFrameLw();
4746
4747 if (frame.left <= 0 && frame.top <= 0) {
4748 // Docked at left or top.
4749 if (frame.bottom >= displayHeight) {
4750 // Docked left.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004751 dockFrame.left = Math.max(frame.right, dockFrame.left);
Wale Ogunwalec0b0f932017-11-01 12:51:43 -07004752 } else if (frame.right >= displayWidth ) {
4753 // Docked top.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004754 dockFrame.top = Math.max(frame.bottom, dockFrame.top);
Wale Ogunwalec0b0f932017-11-01 12:51:43 -07004755 } else {
4756 Slog.w(TAG, "layoutScreenDecorWindows: Ignoring decor win=" + w
4757 + " not docked on left or top of display. frame=" + frame
4758 + " displayWidth=" + displayWidth + " displayHeight=" + displayHeight);
4759 }
4760 } else if (frame.right >= displayWidth && frame.bottom >= displayHeight) {
4761 // Docked at right or bottom.
4762 if (frame.top <= 0) {
4763 // Docked right.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004764 dockFrame.right = Math.min(frame.left, dockFrame.right);
Wale Ogunwalec0b0f932017-11-01 12:51:43 -07004765 } else if (frame.left <= 0) {
4766 // Docked bottom.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004767 dockFrame.bottom = Math.min(frame.top, dockFrame.bottom);
Wale Ogunwalec0b0f932017-11-01 12:51:43 -07004768 } else {
4769 Slog.w(TAG, "layoutScreenDecorWindows: Ignoring decor win=" + w
4770 + " not docked on right or bottom" + " of display. frame=" + frame
4771 + " displayWidth=" + displayWidth + " displayHeight=" + displayHeight);
4772 }
4773 } else {
4774 // Screen decor windows are required to be docked on one of the sides of the screen.
4775 Slog.w(TAG, "layoutScreenDecorWindows: Ignoring decor win=" + w
4776 + " not docked on one of the sides of the display. frame=" + frame
4777 + " displayWidth=" + displayWidth + " displayHeight=" + displayHeight);
4778 }
4779 }
4780
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004781 displayFrames.mRestricted.set(dockFrame);
4782 displayFrames.mCurrent.set(dockFrame);
4783 displayFrames.mVoiceContent.set(dockFrame);
4784 displayFrames.mSystem.set(dockFrame);
4785 displayFrames.mContent.set(dockFrame);
4786 displayFrames.mRestrictedOverscan.set(dockFrame);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004787 }
4788
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004789 private boolean layoutStatusBar(DisplayFrames displayFrames, Rect pf, Rect df, Rect of, Rect vf,
4790 Rect dcf, int sysui, boolean isKeyguardShowing) {
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004791 // decide where the status bar goes ahead of time
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004792 if (mStatusBar == null) {
4793 return false;
4794 }
4795 // apply any navigation bar insets
4796 of.set(displayFrames.mUnrestricted);
4797 df.set(displayFrames.mUnrestricted);
4798 pf.set(displayFrames.mUnrestricted);
4799 vf.set(displayFrames.mStable);
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004800
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004801 mStatusBarLayer = mStatusBar.getSurfaceLayer();
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004802
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004803 // Let the status bar determine its size.
4804 mStatusBar.computeFrameLw(pf /* parentFrame */, df /* displayFrame */,
4805 vf /* overlayFrame */, vf /* contentFrame */, vf /* visibleFrame */,
Adrian Roos5c6b6222017-11-07 17:36:10 +01004806 dcf /* decorFrame */, vf /* stableFrame */, vf /* outsetFrame */,
Adrian Roos5ed644f2018-03-19 17:01:05 +01004807 displayFrames.mDisplayCutout, false /* parentFrameWasClippedByDisplayCutout */);
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004808
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004809 // For layout, the status bar is always at the top with our fixed height.
Adrian Roos22af6502018-02-22 16:57:08 +01004810 displayFrames.mStable.top = displayFrames.mUnrestricted.top
4811 + mStatusBarHeightForRotation[displayFrames.mRotation];
Adrian Roosbc746cd2018-04-16 16:56:07 +02004812 // Make sure the status bar covers the entire cutout height
4813 displayFrames.mStable.top = Math.max(displayFrames.mStable.top,
4814 displayFrames.mDisplayCutoutSafe.top);
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004815
Adrian Roos23df3a32018-03-15 15:41:13 +01004816 // Tell the bar controller where the collapsed status bar content is
4817 mTmpRect.set(mStatusBar.getContentFrameLw());
4818 mTmpRect.intersect(displayFrames.mDisplayCutoutSafe);
4819 mTmpRect.top = mStatusBar.getContentFrameLw().top; // Ignore top display cutout inset
4820 mTmpRect.bottom = displayFrames.mStable.top; // Use collapsed status bar size
4821 mStatusBarController.setContentFrame(mTmpRect);
4822
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004823 boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0;
4824 boolean statusBarTranslucent = (sysui
4825 & (View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT)) != 0;
4826 if (!isKeyguardShowing) {
4827 statusBarTranslucent &= areTranslucentBarsAllowed();
4828 }
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004829
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004830 // If the status bar is hidden, we don't want to cause windows behind it to scroll.
4831 if (mStatusBar.isVisibleLw() && !statusBarTransient) {
4832 // Status bar may go away, so the screen area it occupies is available to apps but just
4833 // covering them when the status bar is visible.
4834 final Rect dockFrame = displayFrames.mDock;
4835 dockFrame.top = displayFrames.mStable.top;
4836 displayFrames.mContent.set(dockFrame);
4837 displayFrames.mVoiceContent.set(dockFrame);
Wale Ogunwaleb773b6c2018-01-09 14:05:36 -08004838 displayFrames.mCurrent.set(dockFrame);
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004839
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004840 if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar: " + String.format(
4841 "dock=%s content=%s cur=%s", dockFrame.toString(),
4842 displayFrames.mContent.toString(), displayFrames.mCurrent.toString()));
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004843
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004844 if (!mStatusBar.isAnimatingLw() && !statusBarTranslucent
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004845 && !mStatusBarController.wasRecentlyTranslucent()) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004846 // If the opaque status bar is currently requested to be visible, and not in the
4847 // process of animating on or off, then we can tell the app that it is covered by it.
4848 displayFrames.mSystem.top = displayFrames.mStable.top;
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004849 }
4850 }
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004851 return mStatusBarController.checkHiddenLw();
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004852 }
4853
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004854 private boolean layoutNavigationBar(DisplayFrames displayFrames, int uiMode, Rect dcf,
Adrian Roos85d202b2016-06-02 16:27:47 -07004855 boolean navVisible, boolean navTranslucent, boolean navAllowedHidden,
Adrian Roosdb1bc6b2016-04-14 17:49:43 -07004856 boolean statusBarExpandedNotKeyguard) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004857 if (mNavigationBar == null) {
4858 return false;
4859 }
4860 boolean transientNavBarShowing = mNavigationBarController.isTransientShowing();
4861 // Force the navigation bar to its appropriate place and size. We need to do this directly,
4862 // instead of relying on it to bubble up from the nav bar, because this needs to change
4863 // atomically with screen rotations.
4864 final int rotation = displayFrames.mRotation;
4865 final int displayHeight = displayFrames.mDisplayHeight;
4866 final int displayWidth = displayFrames.mDisplayWidth;
4867 final Rect dockFrame = displayFrames.mDock;
4868 mNavigationBarPosition = navigationBarPosition(displayWidth, displayHeight, rotation);
4869
Adrian Roosdcc92ed2017-11-22 14:35:58 +01004870 final Rect cutoutSafeUnrestricted = mTmpRect;
4871 cutoutSafeUnrestricted.set(displayFrames.mUnrestricted);
4872 cutoutSafeUnrestricted.intersectUnchecked(displayFrames.mDisplayCutoutSafe);
4873
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004874 if (mNavigationBarPosition == NAV_BAR_BOTTOM) {
4875 // It's a system nav bar or a portrait screen; nav bar goes on bottom.
Adrian Roosdcc92ed2017-11-22 14:35:58 +01004876 final int top = cutoutSafeUnrestricted.bottom
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004877 - getNavigationBarHeight(rotation, uiMode);
Adrian Roos7e58a082018-03-09 16:40:56 +01004878 mTmpNavigationFrame.set(0, top, displayWidth, displayFrames.mUnrestricted.bottom);
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004879 displayFrames.mStable.bottom = displayFrames.mStableFullscreen.bottom = top;
4880 if (transientNavBarShowing) {
4881 mNavigationBarController.setBarShowingLw(true);
4882 } else if (navVisible) {
4883 mNavigationBarController.setBarShowingLw(true);
4884 dockFrame.bottom = displayFrames.mRestricted.bottom
4885 = displayFrames.mRestrictedOverscan.bottom = top;
4886 } else {
4887 // We currently want to hide the navigation UI - unless we expanded the status bar.
4888 mNavigationBarController.setBarShowingLw(statusBarExpandedNotKeyguard);
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004889 }
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004890 if (navVisible && !navTranslucent && !navAllowedHidden
4891 && !mNavigationBar.isAnimatingLw()
4892 && !mNavigationBarController.wasRecentlyTranslucent()) {
4893 // If the opaque nav bar is currently requested to be visible and not in the process
4894 // of animating on or off, then we can tell the app that it is covered by it.
4895 displayFrames.mSystem.bottom = top;
4896 }
4897 } else if (mNavigationBarPosition == NAV_BAR_RIGHT) {
4898 // Landscape screen; nav bar goes to the right.
Adrian Roosdcc92ed2017-11-22 14:35:58 +01004899 final int left = cutoutSafeUnrestricted.right
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004900 - getNavigationBarWidth(rotation, uiMode);
Adrian Roos7e58a082018-03-09 16:40:56 +01004901 mTmpNavigationFrame.set(left, 0, displayFrames.mUnrestricted.right, displayHeight);
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004902 displayFrames.mStable.right = displayFrames.mStableFullscreen.right = left;
4903 if (transientNavBarShowing) {
4904 mNavigationBarController.setBarShowingLw(true);
4905 } else if (navVisible) {
4906 mNavigationBarController.setBarShowingLw(true);
4907 dockFrame.right = displayFrames.mRestricted.right
4908 = displayFrames.mRestrictedOverscan.right = left;
4909 } else {
4910 // We currently want to hide the navigation UI - unless we expanded the status bar.
4911 mNavigationBarController.setBarShowingLw(statusBarExpandedNotKeyguard);
4912 }
4913 if (navVisible && !navTranslucent && !navAllowedHidden
4914 && !mNavigationBar.isAnimatingLw()
4915 && !mNavigationBarController.wasRecentlyTranslucent()) {
4916 // If the nav bar is currently requested to be visible, and not in the process of
4917 // animating on or off, then we can tell the app that it is covered by it.
4918 displayFrames.mSystem.right = left;
4919 }
4920 } else if (mNavigationBarPosition == NAV_BAR_LEFT) {
4921 // Seascape screen; nav bar goes to the left.
Adrian Roosdcc92ed2017-11-22 14:35:58 +01004922 final int right = cutoutSafeUnrestricted.left
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004923 + getNavigationBarWidth(rotation, uiMode);
Adrian Roos7e58a082018-03-09 16:40:56 +01004924 mTmpNavigationFrame.set(displayFrames.mUnrestricted.left, 0, right, displayHeight);
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004925 displayFrames.mStable.left = displayFrames.mStableFullscreen.left = right;
4926 if (transientNavBarShowing) {
4927 mNavigationBarController.setBarShowingLw(true);
4928 } else if (navVisible) {
4929 mNavigationBarController.setBarShowingLw(true);
4930 dockFrame.left = displayFrames.mRestricted.left =
4931 displayFrames.mRestrictedOverscan.left = right;
4932 } else {
4933 // We currently want to hide the navigation UI - unless we expanded the status bar.
4934 mNavigationBarController.setBarShowingLw(statusBarExpandedNotKeyguard);
4935 }
4936 if (navVisible && !navTranslucent && !navAllowedHidden
4937 && !mNavigationBar.isAnimatingLw()
4938 && !mNavigationBarController.wasRecentlyTranslucent()) {
4939 // If the nav bar is currently requested to be visible, and not in the process of
4940 // animating on or off, then we can tell the app that it is covered by it.
4941 displayFrames.mSystem.left = right;
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004942 }
4943 }
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004944
4945 // Make sure the content and current rectangles are updated to account for the restrictions
4946 // from the navigation bar.
4947 displayFrames.mCurrent.set(dockFrame);
4948 displayFrames.mVoiceContent.set(dockFrame);
4949 displayFrames.mContent.set(dockFrame);
4950 mStatusBarLayer = mNavigationBar.getSurfaceLayer();
4951 // And compute the final frame.
4952 mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
Adrian Roos7e58a082018-03-09 16:40:56 +01004953 mTmpNavigationFrame, displayFrames.mDisplayCutoutSafe, mTmpNavigationFrame, dcf,
4954 mTmpNavigationFrame, displayFrames.mDisplayCutoutSafe,
Adrian Roos5ed644f2018-03-19 17:01:05 +01004955 displayFrames.mDisplayCutout, false /* parentFrameWasClippedByDisplayCutout */);
Adrian Roos23df3a32018-03-15 15:41:13 +01004956 mNavigationBarController.setContentFrame(mNavigationBar.getContentFrameLw());
4957
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004958 if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
4959 return mNavigationBarController.checkHiddenLw();
Filip Gruszczynski83dd9552015-09-17 17:50:36 -07004960 }
4961
Yohei Yukawad0a66b22018-01-10 13:19:54 -08004962 @NavigationBarPosition
Adrian Roos85d202b2016-06-02 16:27:47 -07004963 private int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) {
4964 if (mNavigationBarCanMove && displayWidth > displayHeight) {
4965 if (displayRotation == Surface.ROTATION_270) {
4966 return NAV_BAR_LEFT;
4967 } else {
4968 return NAV_BAR_RIGHT;
4969 }
4970 }
4971 return NAV_BAR_BOTTOM;
Jorim Jaggi737af722015-12-31 10:42:27 +01004972 }
4973
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07004974 /** {@inheritDoc} */
Craig Mautner967212c2013-04-13 21:10:58 -07004975 @Override
John Spurlock46646232013-09-30 22:32:42 -04004976 public int getSystemDecorLayerLw() {
Bryce Lee2ed3e5f2015-04-01 22:09:19 +00004977 if (mStatusBar != null && mStatusBar.isVisibleLw()) {
4978 return mStatusBar.getSurfaceLayer();
4979 }
4980
4981 if (mNavigationBar != null && mNavigationBar.isVisibleLw()) {
4982 return mNavigationBar.getSurfaceLayer();
4983 }
4984
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07004985 return 0;
4986 }
4987
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004988 private void setAttachedWindowFrames(WindowState win, int fl, int adjust, WindowState attached,
4989 boolean insetDecors, Rect pf, Rect df, Rect of, Rect cf, Rect vf,
4990 DisplayFrames displayFrames) {
Robert Carr825581a2018-03-30 14:00:53 -07004991 if (!win.isInputMethodTarget() && attached.isInputMethodTarget()) {
4992 // Here's a special case: if the child window is not the 'dock window'
4993 // or input method target, and the window it is attached to is below
4994 // the dock window, then the frames we computed for the window it is
4995 // attached to can not be used because the dock is effectively part
4996 // of the underlying window and the attached window is floating on top
4997 // of the whole thing. So, we ignore the attached window and explicitly
4998 // compute the frames that would be appropriate without the dock.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00004999 vf.set(displayFrames.mDock);
5000 cf.set(displayFrames.mDock);
5001 of.set(displayFrames.mDock);
5002 df.set(displayFrames.mDock);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005003 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005004 // The effective display frame of the attached window depends on whether it is taking
5005 // care of insetting its content. If not, we need to use the parent's content frame so
5006 // that the entire window is positioned within that content. Otherwise we can use the
5007 // overscan frame and let the attached window take care of positioning its content
5008 // appropriately.
Dianne Hackborndea3ef72010-10-28 14:24:22 -07005009 if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
Wale Ogunwale393b1c12014-10-18 16:22:01 -07005010 // Set the content frame of the attached window to the parent's decor frame
5011 // (same as content frame when IME isn't present) if specifically requested by
5012 // setting {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR} flag.
5013 // Otherwise, use the overscan frame.
5014 cf.set((fl & FLAG_LAYOUT_ATTACHED_IN_DECOR) != 0
5015 ? attached.getContentFrameLw() : attached.getOverscanFrameLw());
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005016 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005017 // If the window is resizing, then we want to base the content frame on our attached
5018 // content frame to resize...however, things can be tricky if the attached window is
5019 // NOT in resize mode, in which case its content frame will be larger.
5020 // Ungh. So to deal with that, make sure the content frame we end up using is not
5021 // covering the IM dock.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005022 cf.set(attached.getContentFrameLw());
Dianne Hackborne30e02f2014-05-27 18:24:45 -07005023 if (attached.isVoiceInteraction()) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005024 cf.intersectUnchecked(displayFrames.mVoiceContent);
Robert Carr825581a2018-03-30 14:00:53 -07005025 } else if (win.isInputMethodTarget() || attached.isInputMethodTarget()) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005026 cf.intersectUnchecked(displayFrames.mContent);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005027 }
5028 }
5029 df.set(insetDecors ? attached.getDisplayFrameLw() : cf);
Dianne Hackbornc4aad012013-02-22 15:05:25 -08005030 of.set(insetDecors ? attached.getOverscanFrameLw() : cf);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005031 vf.set(attached.getVisibleFrameLw());
5032 }
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005033 // The LAYOUT_IN_SCREEN flag is used to determine whether the attached window should be
5034 // positioned relative to its parent or the entire screen.
5035 pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0 ? attached.getFrameLw() : df);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005036 }
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07005037
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005038 private void applyStableConstraints(int sysui, int fl, Rect r, DisplayFrames displayFrames) {
5039 if ((sysui & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) == 0) {
5040 return;
5041 }
5042 // If app is requesting a stable layout, don't let the content insets go below the stable
5043 // values.
5044 if ((fl & FLAG_FULLSCREEN) != 0) {
5045 r.intersectUnchecked(displayFrames.mStableFullscreen);
5046 } else {
5047 r.intersectUnchecked(displayFrames.mStable);
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07005048 }
5049 }
5050
Jorim Jaggiaa806142015-05-20 18:04:16 -07005051 private boolean canReceiveInput(WindowState win) {
5052 boolean notFocusable =
5053 (win.getAttrs().flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0;
5054 boolean altFocusableIm =
5055 (win.getAttrs().flags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0;
5056 boolean notFocusableForIm = notFocusable ^ altFocusableIm;
5057 return !notFocusableForIm;
5058 }
5059
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005060 /** {@inheritDoc} */
Craig Mautner69b08182012-09-05 13:07:13 -07005061 @Override
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005062 public void layoutWindowLw(WindowState win, WindowState attached, DisplayFrames displayFrames) {
Wale Ogunwalec0b0f932017-11-01 12:51:43 -07005063 // We've already done the navigation bar, status bar, and all screen decor windows. If the
5064 // status bar can receive input, we need to layout it again to accommodate for the IME
5065 // window.
5066 if ((win == mStatusBar && !canReceiveInput(win)) || win == mNavigationBar
5067 || mScreenDecorWindows.contains(win)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005068 return;
5069 }
Jorim Jaggiaa806142015-05-20 18:04:16 -07005070 final WindowManager.LayoutParams attrs = win.getAttrs();
Craig Mautner69b08182012-09-05 13:07:13 -07005071 final boolean isDefaultDisplay = win.isDefaultDisplay();
5072 final boolean needsToOffsetInputMethodTarget = isDefaultDisplay &&
satok1bc0a492012-04-25 22:47:12 +09005073 (win == mLastInputMethodTargetWindow && mLastInputMethodWindow != null);
5074 if (needsToOffsetInputMethodTarget) {
Craig Mautnereda67292013-04-28 13:50:14 -07005075 if (DEBUG_LAYOUT) Slog.i(TAG, "Offset ime target window by the last ime window state");
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005076 offsetInputMethodWindowLw(mLastInputMethodWindow, displayFrames);
satok1bc0a492012-04-25 22:47:12 +09005077 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005078
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005079 final int type = attrs.type;
John Spurlockc6d1c602014-01-17 15:22:06 -05005080 final int fl = PolicyControl.getWindowFlags(win, attrs);
Jorim Jaggi8f5701b2016-04-04 18:36:02 -07005081 final int pfl = attrs.privateFlags;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005082 final int sim = attrs.softInputMode;
Adrian Roos77373982017-11-24 13:24:28 +01005083 final int requestedSysUiFl = PolicyControl.getSystemUiVisibility(win, null);
5084 final int sysUiFl = requestedSysUiFl | getImpliedSysUiFlagsForLayout(attrs);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07005085
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005086 final Rect pf = mTmpParentFrame;
5087 final Rect df = mTmpDisplayFrame;
Dianne Hackbornc4aad012013-02-22 15:05:25 -08005088 final Rect of = mTmpOverscanFrame;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005089 final Rect cf = mTmpContentFrame;
5090 final Rect vf = mTmpVisibleFrame;
John Spurlock46646232013-09-30 22:32:42 -04005091 final Rect dcf = mTmpDecorFrame;
Adrian Roosfa104232014-06-20 16:10:14 -07005092 final Rect sf = mTmpStableFrame;
Filip Gruszczynski2217f612015-05-26 11:32:08 -07005093 Rect osf = null;
John Spurlock46646232013-09-30 22:32:42 -04005094 dcf.setEmpty();
Craig Mautner69b08182012-09-05 13:07:13 -07005095
5096 final boolean hasNavBar = (isDefaultDisplay && mHasNavigationBar
Daniel Sandler36412a72011-08-04 09:35:13 -04005097 && mNavigationBar != null && mNavigationBar.isVisibleLw());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04005098
Craig Mautnerf683b562012-10-02 11:10:57 -07005099 final int adjust = sim & SOFT_INPUT_MASK_ADJUST;
5100
Adrian Roosdcc92ed2017-11-22 14:35:58 +01005101 final boolean requestedFullscreen = (fl & FLAG_FULLSCREEN) != 0
Adrian Roos2dfb7852018-01-15 13:41:37 +01005102 || (requestedSysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
Adrian Roosdcc92ed2017-11-22 14:35:58 +01005103
5104 final boolean layoutInScreen = (fl & FLAG_LAYOUT_IN_SCREEN) == FLAG_LAYOUT_IN_SCREEN;
5105 final boolean layoutInsetDecor = (fl & FLAG_LAYOUT_INSET_DECOR) == FLAG_LAYOUT_INSET_DECOR;
Adrian Roosdcc92ed2017-11-22 14:35:58 +01005106
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005107 sf.set(displayFrames.mStable);
Adrian Roosfa104232014-06-20 16:10:14 -07005108
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005109 if (type == TYPE_INPUT_METHOD) {
5110 vf.set(displayFrames.mDock);
5111 cf.set(displayFrames.mDock);
5112 of.set(displayFrames.mDock);
5113 df.set(displayFrames.mDock);
5114 pf.set(displayFrames.mDock);
John Spurlockc68d5772013-10-08 11:47:58 -04005115 // IM dock windows layout below the nav bar...
Adrian Roos1f778d52018-03-09 16:59:29 +01005116 pf.bottom = df.bottom = of.bottom = displayFrames.mUnrestricted.bottom;
John Spurlockc68d5772013-10-08 11:47:58 -04005117 // ...with content insets above the nav bar
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005118 cf.bottom = vf.bottom = displayFrames.mStable.bottom;
Adrian Roosdd654ea2016-05-27 11:46:10 -07005119 if (mStatusBar != null && mFocusedWindow == mStatusBar && canReceiveInput(mStatusBar)) {
5120 // The status bar forces the navigation bar while it's visible. Make sure the IME
5121 // avoids the navigation bar in that case.
Adrian Roos85d202b2016-06-02 16:27:47 -07005122 if (mNavigationBarPosition == NAV_BAR_RIGHT) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005123 pf.right = df.right = of.right = cf.right = vf.right =
5124 displayFrames.mStable.right;
Adrian Roos85d202b2016-06-02 16:27:47 -07005125 } else if (mNavigationBarPosition == NAV_BAR_LEFT) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005126 pf.left = df.left = of.left = cf.left = vf.left = displayFrames.mStable.left;
Adrian Roos85d202b2016-06-02 16:27:47 -07005127 }
Adrian Roosdd654ea2016-05-27 11:46:10 -07005128 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005129 // IM dock windows always go to the bottom of the screen.
5130 attrs.gravity = Gravity.BOTTOM;
5131 mDockLayer = win.getSurfaceLayer();
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005132 } else if (type == TYPE_VOICE_INTERACTION) {
5133 of.set(displayFrames.mUnrestricted);
5134 df.set(displayFrames.mUnrestricted);
5135 pf.set(displayFrames.mUnrestricted);
Jorim Jaggi4b74f4d2016-04-27 18:44:08 -07005136 if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005137 cf.set(displayFrames.mDock);
Jorim Jaggi4b74f4d2016-04-27 18:44:08 -07005138 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005139 cf.set(displayFrames.mContent);
Jorim Jaggi4b74f4d2016-04-27 18:44:08 -07005140 }
5141 if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005142 vf.set(displayFrames.mCurrent);
Jorim Jaggi4b74f4d2016-04-27 18:44:08 -07005143 } else {
5144 vf.set(cf);
5145 }
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005146 } else if (type == TYPE_WALLPAPER) {
5147 layoutWallpaper(displayFrames, pf, df, of, cf);
Jorim Jaggiaa806142015-05-20 18:04:16 -07005148 } else if (win == mStatusBar) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005149 of.set(displayFrames.mUnrestricted);
5150 df.set(displayFrames.mUnrestricted);
5151 pf.set(displayFrames.mUnrestricted);
5152 cf.set(displayFrames.mStable);
5153 vf.set(displayFrames.mStable);
Adrian Roosdc5b4532016-01-06 20:49:41 +01005154
5155 if (adjust == SOFT_INPUT_ADJUST_RESIZE) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005156 cf.bottom = displayFrames.mContent.bottom;
Adrian Roosdc5b4532016-01-06 20:49:41 +01005157 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005158 cf.bottom = displayFrames.mDock.bottom;
5159 vf.bottom = displayFrames.mContent.bottom;
Adrian Roosdc5b4532016-01-06 20:49:41 +01005160 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005161 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005162 dcf.set(displayFrames.mSystem);
5163 final boolean inheritTranslucentDecor =
5164 (attrs.privateFlags & PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR) != 0;
John Spurlock65567d42013-10-08 10:08:32 -04005165 final boolean isAppWindow =
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005166 type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW;
John Spurlock65567d42013-10-08 10:08:32 -04005167 final boolean topAtRest =
5168 win == mTopFullscreenOpaqueWindowState && !win.isAnimatingLw();
5169 if (isAppWindow && !inheritTranslucentDecor && !topAtRest) {
John Spurlockbd957402013-10-03 11:38:39 -04005170 if ((sysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005171 && (fl & FLAG_FULLSCREEN) == 0
5172 && (fl & FLAG_TRANSLUCENT_STATUS) == 0
5173 && (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
Jorim Jaggi8f5701b2016-04-04 18:36:02 -07005174 && (pfl & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) == 0) {
John Spurlock46646232013-09-30 22:32:42 -04005175 // Ensure policy decor includes status bar
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005176 dcf.top = displayFrames.mStable.top;
John Spurlock46646232013-09-30 22:32:42 -04005177 }
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005178 if ((fl & FLAG_TRANSLUCENT_NAVIGATION) == 0
Adrian Roosea562512014-05-05 13:33:03 +02005179 && (sysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005180 && (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0) {
John Spurlock46646232013-09-30 22:32:42 -04005181 // Ensure policy decor includes navigation bar
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005182 dcf.bottom = displayFrames.mStable.bottom;
5183 dcf.right = displayFrames.mStable.right;
John Spurlock46646232013-09-30 22:32:42 -04005184 }
5185 }
5186
Adrian Roosdcc92ed2017-11-22 14:35:58 +01005187 if (layoutInScreen && layoutInsetDecor) {
RoboErik8a2cfc32014-05-16 11:19:38 -07005188 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle()
Dianne Hackbornc4aad012013-02-22 15:05:25 -08005189 + "): IN_SCREEN, INSET_DECOR");
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005190 // This is the case for a normal activity window: we want it to cover all of the
5191 // screen space, and it can take care of moving its contents to account for screen
5192 // decorations that intrude into that space.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005193 if (attached != null) {
5194 // If this window is attached to another, our display
5195 // frame is the same as the one we are attached to.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005196 setAttachedWindowFrames(win, fl, adjust, attached, true, pf, df, of, cf, vf,
5197 displayFrames);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005198 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005199 if (type == TYPE_STATUS_BAR_PANEL || type == TYPE_STATUS_BAR_SUB_PANEL) {
5200 // Status bar panels are the only windows who can go on top of the status
5201 // bar. They are protected by the STATUS_BAR_SERVICE permission, so they
5202 // have the same privileges as the status bar itself.
Daniel Sandler8956dbb2011-04-22 07:55:02 -04005203 //
Daniel Sandler8e8b4152011-07-21 01:16:43 -04005204 // However, they should still dodge the navigation bar if it exists.
Daniel Sandler8956dbb2011-04-22 07:55:02 -04005205
Dianne Hackbornc4aad012013-02-22 15:05:25 -08005206 pf.left = df.left = of.left = hasNavBar
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005207 ? displayFrames.mDock.left : displayFrames.mUnrestricted.left;
5208 pf.top = df.top = of.top = displayFrames.mUnrestricted.top;
Dianne Hackbornc4aad012013-02-22 15:05:25 -08005209 pf.right = df.right = of.right = hasNavBar
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005210 ? displayFrames.mRestricted.right
5211 : displayFrames.mUnrestricted.right;
Dianne Hackbornc4aad012013-02-22 15:05:25 -08005212 pf.bottom = df.bottom = of.bottom = hasNavBar
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005213 ? displayFrames.mRestricted.bottom
5214 : displayFrames.mUnrestricted.bottom;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04005215
Craig Mautnereda67292013-04-28 13:50:14 -07005216 if (DEBUG_LAYOUT) Slog.v(TAG, String.format(
Daniel Sandler8e8b4152011-07-21 01:16:43 -04005217 "Laying out status bar window: (%d,%d - %d,%d)",
5218 pf.left, pf.top, pf.right, pf.bottom));
John Spurlock46646232013-09-30 22:32:42 -04005219 } else if ((fl & FLAG_LAYOUT_IN_OVERSCAN) != 0
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005220 && type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08005221 // Asking to layout into the overscan region, so give it that pure
5222 // unrestricted area.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005223 of.set(displayFrames.mOverscan);
5224 df.set(displayFrames.mOverscan);
5225 pf.set(displayFrames.mOverscan);
Alan Viverette5a0f4ec2013-10-07 15:10:29 -07005226 } else if (canHideNavigationBar()
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005227 && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
Adrian Roosedfab3b2018-03-08 18:39:20 +01005228 && (type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW
5229 || type == TYPE_VOLUME_OVERLAY)) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005230 // Asking for layout as if the nav bar is hidden, lets the application
5231 // extend into the unrestricted overscan screen area. We only do this for
Adrian Roosedfab3b2018-03-08 18:39:20 +01005232 // application windows and certain system windows to ensure no window that
5233 // can be above the nav bar can do this.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005234 df.set(displayFrames.mOverscan);
5235 pf.set(displayFrames.mOverscan);
5236 // We need to tell the app about where the frame inside the overscan is, so
5237 // it can inset its content by that amount -- it didn't ask to actually
5238 // extend itself into the overscan region.
5239 of.set(displayFrames.mUnrestricted);
Wale Ogunwale7bb06e02017-11-13 16:49:19 +00005240 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005241 df.set(displayFrames.mRestrictedOverscan);
5242 pf.set(displayFrames.mRestrictedOverscan);
Wale Ogunwale7bb06e02017-11-13 16:49:19 +00005243 // We need to tell the app about where the frame inside the overscan
5244 // is, so it can inset its content by that amount -- it didn't ask
5245 // to actually extend itself into the overscan region.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005246 of.set(displayFrames.mUnrestricted);
Joe Onorato29fc2c92010-11-24 10:26:50 -08005247 }
Craig Mautner69b08182012-09-05 13:07:13 -07005248
John Spurlock46646232013-09-30 22:32:42 -04005249 if ((fl & FLAG_FULLSCREEN) == 0) {
Dianne Hackborne30e02f2014-05-27 18:24:45 -07005250 if (win.isVoiceInteraction()) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005251 cf.set(displayFrames.mVoiceContent);
Dianne Hackbornc4aad012013-02-22 15:05:25 -08005252 } else {
Dianne Hackborne30e02f2014-05-27 18:24:45 -07005253 if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005254 cf.set(displayFrames.mDock);
Dianne Hackborne30e02f2014-05-27 18:24:45 -07005255 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005256 cf.set(displayFrames.mContent);
Dianne Hackborne30e02f2014-05-27 18:24:45 -07005257 }
Dianne Hackbornc4aad012013-02-22 15:05:25 -08005258 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005259 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005260 // Full screen windows are always given a layout that is as if the status
5261 // bar and other transient decors are gone. This is to avoid bad states when
5262 // moving from a window that is not hiding the status bar to one that is.
5263 cf.set(displayFrames.mRestricted);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005264 }
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005265 applyStableConstraints(sysUiFl, fl, cf, displayFrames);
Dianne Hackborndea3ef72010-10-28 14:24:22 -07005266 if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005267 vf.set(displayFrames.mCurrent);
Dianne Hackborndea3ef72010-10-28 14:24:22 -07005268 } else {
5269 vf.set(cf);
5270 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005271 }
Adrian Roosdcc92ed2017-11-22 14:35:58 +01005272 } else if (layoutInScreen || (sysUiFl
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07005273 & (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
5274 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)) != 0) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005275 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle()
5276 + "): IN_SCREEN");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005277 // A window that has requested to fill the entire screen just
5278 // gets everything, period.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005279 if (type == TYPE_STATUS_BAR_PANEL || type == TYPE_STATUS_BAR_SUB_PANEL) {
5280 cf.set(displayFrames.mUnrestricted);
5281 of.set(displayFrames.mUnrestricted);
5282 df.set(displayFrames.mUnrestricted);
5283 pf.set(displayFrames.mUnrestricted);
5284 if (hasNavBar) {
5285 pf.left = df.left = of.left = cf.left = displayFrames.mDock.left;
5286 pf.right = df.right = of.right = cf.right = displayFrames.mRestricted.right;
5287 pf.bottom = df.bottom = of.bottom = cf.bottom =
5288 displayFrames.mRestricted.bottom;
5289 }
Lucas Dupinc1cc7592017-05-22 15:56:16 -07005290 if (DEBUG_LAYOUT) Slog.v(TAG, String.format(
5291 "Laying out IN_SCREEN status bar window: (%d,%d - %d,%d)",
5292 pf.left, pf.top, pf.right, pf.bottom));
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005293 } else if (type == TYPE_NAVIGATION_BAR || type == TYPE_NAVIGATION_BAR_PANEL) {
Daniel Sandler8e8b4152011-07-21 01:16:43 -04005294 // The navigation bar has Real Ultimate Power.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005295 of.set(displayFrames.mUnrestricted);
5296 df.set(displayFrames.mUnrestricted);
5297 pf.set(displayFrames.mUnrestricted);
Craig Mautnereda67292013-04-28 13:50:14 -07005298 if (DEBUG_LAYOUT) Slog.v(TAG, String.format(
Daniel Sandler8e8b4152011-07-21 01:16:43 -04005299 "Laying out navigation bar window: (%d,%d - %d,%d)",
5300 pf.left, pf.top, pf.right, pf.bottom));
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005301 } else if ((type == TYPE_SECURE_SYSTEM_OVERLAY || type == TYPE_SCREENSHOT)
Jeff Brownbfcb60a2011-09-08 18:51:14 -07005302 && ((fl & FLAG_FULLSCREEN) != 0)) {
Muyuan Li6ca619f2016-03-08 13:30:42 -08005303 // Fullscreen secure system overlays get what they ask for. Screenshot region
5304 // selection overlay should also expand to full screen.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005305 cf.set(displayFrames.mOverscan);
5306 of.set(displayFrames.mOverscan);
5307 df.set(displayFrames.mOverscan);
5308 pf.set(displayFrames.mOverscan);
5309 } else if (type == TYPE_BOOT_PROGRESS) {
Dianne Hackborn01011c32012-02-21 13:54:21 -08005310 // Boot progress screen always covers entire display.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005311 cf.set(displayFrames.mOverscan);
5312 of.set(displayFrames.mOverscan);
5313 df.set(displayFrames.mOverscan);
5314 pf.set(displayFrames.mOverscan);
John Spurlock46646232013-09-30 22:32:42 -04005315 } else if ((fl & FLAG_LAYOUT_IN_OVERSCAN) != 0
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005316 && type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW) {
5317 // Asking to layout into the overscan region, so give it that pure unrestricted
5318 // area.
5319 cf.set(displayFrames.mOverscan);
5320 of.set(displayFrames.mOverscan);
5321 df.set(displayFrames.mOverscan);
5322 pf.set(displayFrames.mOverscan);
Alan Viverette5a0f4ec2013-10-07 15:10:29 -07005323 } else if (canHideNavigationBar()
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005324 && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005325 && (type == TYPE_STATUS_BAR
5326 || type == TYPE_TOAST
5327 || type == TYPE_DOCK_DIVIDER
5328 || type == TYPE_VOICE_INTERACTION_STARTING
5329 || (type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW))) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07005330 // Asking for layout as if the nav bar is hidden, lets the
5331 // application extend into the unrestricted screen area. We
John Spurlock34e13d92013-08-10 06:52:28 -04005332 // only do this for application windows (or toasts) to ensure no window that
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07005333 // can be above the nav bar can do this.
5334 // XXX This assumes that an app asking for this will also
5335 // ask for layout in only content. We can't currently figure out
5336 // what the screen would be if only laying out to hide the nav bar.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005337 cf.set(displayFrames.mUnrestricted);
5338 of.set(displayFrames.mUnrestricted);
5339 df.set(displayFrames.mUnrestricted);
5340 pf.set(displayFrames.mUnrestricted);
Jorim Jaggi9f6798a2016-02-10 22:16:06 -08005341 } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005342 of.set(displayFrames.mRestricted);
5343 df.set(displayFrames.mRestricted);
5344 pf.set(displayFrames.mRestricted);
Jorim Jaggi9f6798a2016-02-10 22:16:06 -08005345 if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005346 cf.set(displayFrames.mDock);
Jorim Jaggi9f6798a2016-02-10 22:16:06 -08005347 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005348 cf.set(displayFrames.mContent);
Jorim Jaggi9f6798a2016-02-10 22:16:06 -08005349 }
Joe Onorato29fc2c92010-11-24 10:26:50 -08005350 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005351 cf.set(displayFrames.mRestricted);
5352 of.set(displayFrames.mRestricted);
5353 df.set(displayFrames.mRestricted);
5354 pf.set(displayFrames.mRestricted);
Joe Onorato29fc2c92010-11-24 10:26:50 -08005355 }
Craig Mautner69b08182012-09-05 13:07:13 -07005356
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005357 applyStableConstraints(sysUiFl, fl, cf,displayFrames);
Craig Mautner69b08182012-09-05 13:07:13 -07005358
Dianne Hackborndea3ef72010-10-28 14:24:22 -07005359 if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005360 vf.set(displayFrames.mCurrent);
Dianne Hackborndea3ef72010-10-28 14:24:22 -07005361 } else {
5362 vf.set(cf);
5363 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005364 } else if (attached != null) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005365 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle()
5366 + "): attached to " + attached);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005367 // A child window should be placed inside of the same visible
5368 // frame that its parent had.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005369 setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, of, cf, vf,
5370 displayFrames);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005371 } else {
Craig Mautnereda67292013-04-28 13:50:14 -07005372 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() +
5373 "): normal window");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005374 // Otherwise, a normal window must be placed inside the content
5375 // of all screen decorations.
Adrian Roosedfab3b2018-03-08 18:39:20 +01005376 if (type == TYPE_STATUS_BAR_PANEL) {
5377 // Status bar panels can go on
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005378 // top of the status bar. They are protected by the STATUS_BAR_SERVICE
5379 // permission, so they have the same privileges as the status bar itself.
5380 cf.set(displayFrames.mRestricted);
5381 of.set(displayFrames.mRestricted);
5382 df.set(displayFrames.mRestricted);
5383 pf.set(displayFrames.mRestricted);
5384 } else if (type == TYPE_TOAST || type == TYPE_SYSTEM_ALERT) {
John Spurlock414c1f02013-12-04 13:47:36 -05005385 // These dialogs are stable to interim decor changes.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005386 cf.set(displayFrames.mStable);
5387 of.set(displayFrames.mStable);
5388 df.set(displayFrames.mStable);
5389 pf.set(displayFrames.mStable);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005390 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005391 pf.set(displayFrames.mContent);
Dianne Hackborn20d94742014-05-29 18:35:45 -07005392 if (win.isVoiceInteraction()) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005393 cf.set(displayFrames.mVoiceContent);
5394 of.set(displayFrames.mVoiceContent);
5395 df.set(displayFrames.mVoiceContent);
Dianne Hackborn20d94742014-05-29 18:35:45 -07005396 } else if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005397 cf.set(displayFrames.mDock);
5398 of.set(displayFrames.mDock);
5399 df.set(displayFrames.mDock);
Dianne Hackborna239c842011-06-01 12:28:20 -07005400 } else {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005401 cf.set(displayFrames.mContent);
5402 of.set(displayFrames.mContent);
5403 df.set(displayFrames.mContent);
Dianne Hackborna239c842011-06-01 12:28:20 -07005404 }
5405 if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005406 vf.set(displayFrames.mCurrent);
Dianne Hackborna239c842011-06-01 12:28:20 -07005407 } else {
5408 vf.set(cf);
5409 }
Dianne Hackborndea3ef72010-10-28 14:24:22 -07005410 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005411 }
5412 }
Craig Mautner69b08182012-09-05 13:07:13 -07005413
Adrian Roos5ed644f2018-03-19 17:01:05 +01005414 boolean parentFrameWasClippedByDisplayCutout = false;
Adrian Roosfa02da62018-01-15 16:01:18 +01005415 final int cutoutMode = attrs.layoutInDisplayCutoutMode;
Adrian Roosa7f9b842018-02-16 19:35:27 +01005416 final boolean attachedInParent = attached != null && !layoutInScreen;
Adrian Roos7e58a082018-03-09 16:40:56 +01005417 final boolean requestedHideNavigation =
5418 (requestedSysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
Adrian Roosc8045bf2018-03-29 19:41:30 +02005419
5420 // TYPE_BASE_APPLICATION windows are never considered floating here because they don't get
5421 // cropped / shifted to the displayFrame in WindowState.
5422 final boolean floatingInScreenWindow = !attrs.isFullscreen() && layoutInScreen
5423 && type != TYPE_BASE_APPLICATION;
5424
Adrian Roosfa02da62018-01-15 16:01:18 +01005425 // Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in
5426 // the cutout safe zone.
Adrian Rooseb3697c2018-02-21 17:32:44 +01005427 if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
Adrian Roos5ed644f2018-03-19 17:01:05 +01005428 final Rect displayCutoutSafeExceptMaybeBars = mTmpDisplayCutoutSafeExceptMaybeBarsRect;
Adrian Roos7e58a082018-03-09 16:40:56 +01005429 displayCutoutSafeExceptMaybeBars.set(displayFrames.mDisplayCutoutSafe);
Adrian Roosfa02da62018-01-15 16:01:18 +01005430 if (layoutInScreen && layoutInsetDecor && !requestedFullscreen
5431 && cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT) {
Adrian Roosdcc92ed2017-11-22 14:35:58 +01005432 // At the top we have the status bar, so apps that are
Adrian Roosfa02da62018-01-15 16:01:18 +01005433 // LAYOUT_IN_SCREEN | LAYOUT_INSET_DECOR but not FULLSCREEN
5434 // already expect that there's an inset there and we don't need to exclude
5435 // the window from that area.
Adrian Roos7e58a082018-03-09 16:40:56 +01005436 displayCutoutSafeExceptMaybeBars.top = Integer.MIN_VALUE;
5437 }
5438 if (layoutInScreen && layoutInsetDecor && !requestedHideNavigation
5439 && cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT) {
5440 // Same for the navigation bar.
5441 switch (mNavigationBarPosition) {
5442 case NAV_BAR_BOTTOM:
5443 displayCutoutSafeExceptMaybeBars.bottom = Integer.MAX_VALUE;
5444 break;
5445 case NAV_BAR_RIGHT:
5446 displayCutoutSafeExceptMaybeBars.right = Integer.MAX_VALUE;
5447 break;
5448 case NAV_BAR_LEFT:
5449 displayCutoutSafeExceptMaybeBars.left = Integer.MIN_VALUE;
5450 break;
5451 }
Adrian Roosdcc92ed2017-11-22 14:35:58 +01005452 }
Adrian Roos1f778d52018-03-09 16:59:29 +01005453 if (type == TYPE_INPUT_METHOD && mNavigationBarPosition == NAV_BAR_BOTTOM) {
5454 // The IME can always extend under the bottom cutout if the navbar is there.
5455 displayCutoutSafeExceptMaybeBars.bottom = Integer.MAX_VALUE;
Adrian Roosdcc92ed2017-11-22 14:35:58 +01005456 }
Adrian Roos5ed644f2018-03-19 17:01:05 +01005457 // Windows that are attached to a parent and laid out in said parent already avoid
5458 // the cutout according to that parent and don't need to be further constrained.
Adrian Roosc8045bf2018-03-29 19:41:30 +02005459 // Floating IN_SCREEN windows get what they ask for and lay out in the full screen.
5460 // They will later be cropped or shifted using the displayFrame in WindowState,
5461 // which prevents overlap with the DisplayCutout.
5462 if (!attachedInParent && !floatingInScreenWindow) {
Adrian Roos5ed644f2018-03-19 17:01:05 +01005463 mTmpRect.set(pf);
Adrian Roos7e58a082018-03-09 16:40:56 +01005464 pf.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
Adrian Roos5ed644f2018-03-19 17:01:05 +01005465 parentFrameWasClippedByDisplayCutout |= !mTmpRect.equals(pf);
Adrian Rooseb3697c2018-02-21 17:32:44 +01005466 }
Adrian Roos7e58a082018-03-09 16:40:56 +01005467 // Make sure that NO_LIMITS windows clipped to the display don't extend under the
5468 // cutout.
5469 df.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
Adrian Roosdcc92ed2017-11-22 14:35:58 +01005470 }
5471
5472 // Content should never appear in the cutout.
5473 cf.intersectUnchecked(displayFrames.mDisplayCutoutSafe);
5474
Craig Mautnerb816bed2013-07-23 10:26:17 -07005475 // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it.
Wale Ogunwale9185fb02016-03-11 18:06:14 -08005476 // Also, we don't allow windows in multi-window mode to extend out of the screen.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005477 if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && type != TYPE_SYSTEM_ERROR
Andrii Kulian933076d2016-03-29 17:04:42 -07005478 && !win.isInMultiWindowMode()) {
Dianne Hackborn067e5f62014-09-07 23:14:30 -07005479 df.left = df.top = -10000;
5480 df.right = df.bottom = 10000;
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005481 if (type != TYPE_WALLPAPER) {
Dianne Hackborn067e5f62014-09-07 23:14:30 -07005482 of.left = of.top = cf.left = cf.top = vf.left = vf.top = -10000;
5483 of.right = of.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000;
5484 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005485 }
5486
Filip Gruszczynski2217f612015-05-26 11:32:08 -07005487 // If the device has a chin (e.g. some watches), a dead area at the bottom of the screen we
5488 // need to provide information to the clients that want to pretend that you can draw there.
Filip Gruszczynskib0c673b2015-06-05 09:43:06 -07005489 // We only want to apply outsets to certain types of windows. For example, we never want to
5490 // apply the outsets to floating dialogs, because they wouldn't make sense there.
Filip Gruszczynski2987f612015-06-30 15:03:30 -07005491 final boolean useOutsets = shouldUseOutsets(attrs, fl);
Filip Gruszczynskib0c673b2015-06-05 09:43:06 -07005492 if (isDefaultDisplay && useOutsets) {
Filip Gruszczynski2217f612015-05-26 11:32:08 -07005493 osf = mTmpOutsetFrame;
5494 osf.set(cf.left, cf.top, cf.right, cf.bottom);
5495 int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources());
5496 if (outset > 0) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005497 int rotation = displayFrames.mRotation;
Filip Gruszczynski2217f612015-05-26 11:32:08 -07005498 if (rotation == Surface.ROTATION_0) {
5499 osf.bottom += outset;
5500 } else if (rotation == Surface.ROTATION_90) {
5501 osf.right += outset;
5502 } else if (rotation == Surface.ROTATION_180) {
5503 osf.top -= outset;
5504 } else if (rotation == Surface.ROTATION_270) {
5505 osf.left -= outset;
5506 }
5507 if (DEBUG_LAYOUT) Slog.v(TAG, "applying bottom outset of " + outset
5508 + " with rotation " + rotation + ", result: " + osf);
5509 }
5510 }
5511
Craig Mautnereda67292013-04-28 13:50:14 -07005512 if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()
The Android Open Source Project11267662009-03-18 17:39:47 -07005513 + ": sim=#" + Integer.toHexString(sim)
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005514 + " attach=" + attached + " type=" + type
Daniel Sandler8956dbb2011-04-22 07:55:02 -04005515 + String.format(" flags=0x%08x", fl)
The Android Open Source Project11267662009-03-18 17:39:47 -07005516 + " pf=" + pf.toShortString() + " df=" + df.toShortString()
Dianne Hackbornc4aad012013-02-22 15:05:25 -08005517 + " of=" + of.toShortString()
John Spurlock46646232013-09-30 22:32:42 -04005518 + " cf=" + cf.toShortString() + " vf=" + vf.toShortString()
Adrian Roosfa104232014-06-20 16:10:14 -07005519 + " dcf=" + dcf.toShortString()
Filip Gruszczynski2217f612015-05-26 11:32:08 -07005520 + " sf=" + sf.toShortString()
5521 + " osf=" + (osf == null ? "null" : osf.toShortString()));
Craig Mautner69b08182012-09-05 13:07:13 -07005522
Adrian Roos5ed644f2018-03-19 17:01:05 +01005523 win.computeFrameLw(pf, df, of, cf, vf, dcf, sf, osf, displayFrames.mDisplayCutout,
5524 parentFrameWasClippedByDisplayCutout);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005525 // Dock windows carve out the bottom of the screen, so normal windows
5526 // can't appear underneath them.
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005527 if (type == TYPE_INPUT_METHOD && win.isVisibleLw()
Jorim Jaggib0d27342016-11-01 16:10:42 -07005528 && !win.getGivenInsetsPendingLw()) {
satok1bc0a492012-04-25 22:47:12 +09005529 setLastInputMethodWindowLw(null, null);
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005530 offsetInputMethodWindowLw(win, displayFrames);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005531 }
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005532 if (type == TYPE_VOICE_INTERACTION && win.isVisibleLw()
Dianne Hackborne30e02f2014-05-27 18:24:45 -07005533 && !win.getGivenInsetsPendingLw()) {
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005534 offsetVoiceInputWindowLw(win, displayFrames);
Dianne Hackborne30e02f2014-05-27 18:24:45 -07005535 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005536 }
5537
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005538 private void layoutWallpaper(DisplayFrames displayFrames, Rect pf, Rect df, Rect of, Rect cf) {
5539 // The wallpaper has Real Ultimate Power, but we want to tell it about the overscan area.
5540 df.set(displayFrames.mOverscan);
5541 pf.set(displayFrames.mOverscan);
5542 cf.set(displayFrames.mUnrestricted);
5543 of.set(displayFrames.mUnrestricted);
Jorim Jaggi526505d2016-05-24 00:29:19 -07005544 }
5545
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005546 private void offsetInputMethodWindowLw(WindowState win, DisplayFrames displayFrames) {
Craig Mautner4774f6a2015-03-23 11:42:55 -07005547 int top = Math.max(win.getDisplayFrameLw().top, win.getContentFrameLw().top);
satok1bc0a492012-04-25 22:47:12 +09005548 top += win.getGivenContentInsetsLw().top;
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005549 displayFrames.mContent.bottom = Math.min(displayFrames.mContent.bottom, top);
5550 displayFrames.mVoiceContent.bottom = Math.min(displayFrames.mVoiceContent.bottom, top);
satok1bc0a492012-04-25 22:47:12 +09005551 top = win.getVisibleFrameLw().top;
5552 top += win.getGivenVisibleInsetsLw().top;
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005553 displayFrames.mCurrent.bottom = Math.min(displayFrames.mCurrent.bottom, top);
Craig Mautnereda67292013-04-28 13:50:14 -07005554 if (DEBUG_LAYOUT) Slog.v(TAG, "Input method: mDockBottom="
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005555 + displayFrames.mDock.bottom + " mContentBottom="
5556 + displayFrames.mContent.bottom + " mCurBottom=" + displayFrames.mCurrent.bottom);
satok1bc0a492012-04-25 22:47:12 +09005557 }
5558
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005559 private void offsetVoiceInputWindowLw(WindowState win, DisplayFrames displayFrames) {
Craig Mautner4774f6a2015-03-23 11:42:55 -07005560 int top = Math.max(win.getDisplayFrameLw().top, win.getContentFrameLw().top);
Dianne Hackbornae6688b2015-02-11 17:02:41 -08005561 top += win.getGivenContentInsetsLw().top;
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00005562 displayFrames.mVoiceContent.bottom = Math.min(displayFrames.mVoiceContent.bottom, top);
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08005563 }
5564
5565 /** {@inheritDoc} */
Craig Mautnerad09bcc2012-10-08 13:33:11 -07005566 @Override
Craig Mautner39834192012-09-02 07:47:24 -07005567 public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) {
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08005568 mTopFullscreenOpaqueWindowState = null;
Adrian Rooscd3884d2015-02-18 17:25:23 +01005569 mTopFullscreenOpaqueOrDimmingWindowState = null;
Jorim Jaggi86905582016-02-09 21:36:09 -08005570 mTopDockedOpaqueWindowState = null;
5571 mTopDockedOpaqueOrDimmingWindowState = null;
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08005572 mForceStatusBar = false;
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07005573 mForceStatusBarFromKeyguard = false;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07005574 mForceStatusBarTransparent = false;
Dianne Hackborn891d3fb2013-01-09 18:31:37 -08005575 mForcingShowNavBar = false;
5576 mForcingShowNavBarLayer = -1;
RoboErik8a2cfc32014-05-16 11:19:38 -07005577
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08005578 mAllowLockscreenWhenOn = false;
Dianne Hackborn7ad44382012-10-18 17:46:00 -07005579 mShowingDream = false;
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02005580 mWindowSleepTokenNeeded = false;
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08005581 }
5582
5583 /** {@inheritDoc} */
Craig Mautnerad09bcc2012-10-08 13:33:11 -07005584 @Override
Yohei Yukawad1a09222015-06-30 16:22:05 -07005585 public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs,
Jorim Jaggife762342016-10-13 14:33:27 +02005586 WindowState attached, WindowState imeTarget) {
Jorim Jaggi23cc9aa2017-05-23 16:05:35 +02005587 final boolean affectsSystemUi = win.canAffectSystemUiFlags();
5588 if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": affectsSystemUi=" + affectsSystemUi);
Jorim Jaggife762342016-10-13 14:33:27 +02005589 applyKeyguardPolicyLw(win, imeTarget);
John Spurlockc6d1c602014-01-17 15:22:06 -05005590 final int fl = PolicyControl.getWindowFlags(win, attrs);
Jorim Jaggi23cc9aa2017-05-23 16:05:35 +02005591 if (mTopFullscreenOpaqueWindowState == null && affectsSystemUi
5592 && attrs.type == TYPE_INPUT_METHOD) {
John Spurlock414c1f02013-12-04 13:47:36 -05005593 mForcingShowNavBar = true;
5594 mForcingShowNavBarLayer = win.getSurfaceLayer();
Dianne Hackborn891d3fb2013-01-09 18:31:37 -08005595 }
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07005596 if (attrs.type == TYPE_STATUS_BAR) {
5597 if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
5598 mForceStatusBarFromKeyguard = true;
5599 }
5600 if ((attrs.privateFlags & PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT) != 0) {
5601 mForceStatusBarTransparent = true;
5602 }
Jorim Jaggiafd4a552014-04-08 15:13:05 +02005603 }
Adrian Roos602c68e2015-04-24 16:03:47 -07005604
5605 boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
Jorim Jaggi30d64f32017-04-07 16:33:17 +02005606 && attrs.type < FIRST_SYSTEM_WINDOW;
Wale Ogunwale44f036f2017-09-29 05:09:09 -07005607 final int windowingMode = win.getWindowingMode();
5608 final boolean inFullScreenOrSplitScreenSecondaryWindowingMode =
5609 windowingMode == WINDOWING_MODE_FULLSCREEN
5610 || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Jorim Jaggi23cc9aa2017-05-23 16:05:35 +02005611 if (mTopFullscreenOpaqueWindowState == null && affectsSystemUi) {
John Spurlockc6d1c602014-01-17 15:22:06 -05005612 if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
Jorim Jaggife762342016-10-13 14:33:27 +02005613 mForceStatusBar = true;
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07005614 }
Dianne Hackborn7ad44382012-10-18 17:46:00 -07005615 if (attrs.type == TYPE_DREAM) {
Jeff Brownc8018eb2012-10-29 21:33:27 -07005616 // If the lockscreen was showing when the dream started then wait
5617 // for the dream to draw before hiding the lockscreen.
5618 if (!mDreamingLockscreen
5619 || (win.isVisibleLw() && win.hasDrawnLw())) {
5620 mShowingDream = true;
Craig Mautnerab55e522014-03-03 13:26:03 -08005621 appWindow = true;
Dianne Hackborn7ad44382012-10-18 17:46:00 -07005622 }
5623 }
Craig Mautnerab55e522014-03-03 13:26:03 -08005624
Yohei Yukawad1a09222015-06-30 16:22:05 -07005625 // For app windows that are not attached, we decide if all windows in the app they
5626 // represent should be hidden or if we should hide the lockscreen. For attached app
5627 // windows we defer the decision to the window it is attached to.
5628 if (appWindow && attached == null) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07005629 if (attrs.isFullscreen() && inFullScreenOrSplitScreenSecondaryWindowingMode) {
Craig Mautnerab55e522014-03-03 13:26:03 -08005630 if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
5631 mTopFullscreenOpaqueWindowState = win;
Adrian Rooscd3884d2015-02-18 17:25:23 +01005632 if (mTopFullscreenOpaqueOrDimmingWindowState == null) {
5633 mTopFullscreenOpaqueOrDimmingWindowState = win;
5634 }
Craig Mautner00156ec2014-03-06 22:29:02 -08005635 if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
Craig Mautnerab55e522014-03-03 13:26:03 -08005636 mAllowLockscreenWhenOn = true;
5637 }
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08005638 }
Adrian Roos602c68e2015-04-24 16:03:47 -07005639 }
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08005640 }
Jorim Jaggi86905582016-02-09 21:36:09 -08005641
Jorim Jaggi90859bc2016-06-28 16:25:23 -07005642 // Voice interaction overrides both top fullscreen and top docked.
Jorim Jaggi23cc9aa2017-05-23 16:05:35 +02005643 if (affectsSystemUi && win.getAttrs().type == TYPE_VOICE_INTERACTION) {
Jorim Jaggi90859bc2016-06-28 16:25:23 -07005644 if (mTopFullscreenOpaqueWindowState == null) {
5645 mTopFullscreenOpaqueWindowState = win;
5646 if (mTopFullscreenOpaqueOrDimmingWindowState == null) {
5647 mTopFullscreenOpaqueOrDimmingWindowState = win;
5648 }
5649 }
5650 if (mTopDockedOpaqueWindowState == null) {
5651 mTopDockedOpaqueWindowState = win;
5652 if (mTopDockedOpaqueOrDimmingWindowState == null) {
5653 mTopDockedOpaqueOrDimmingWindowState = win;
5654 }
5655 }
5656 }
5657
5658 // Keep track of the window if it's dimming but not necessarily fullscreen.
Jorim Jaggi23cc9aa2017-05-23 16:05:35 +02005659 if (mTopFullscreenOpaqueOrDimmingWindowState == null && affectsSystemUi
Wale Ogunwale44f036f2017-09-29 05:09:09 -07005660 && win.isDimming() && inFullScreenOrSplitScreenSecondaryWindowingMode) {
Adrian Rooscd3884d2015-02-18 17:25:23 +01005661 mTopFullscreenOpaqueOrDimmingWindowState = win;
5662 }
Jorim Jaggi86905582016-02-09 21:36:09 -08005663
5664 // We need to keep track of the top "fullscreen" opaque window for the docked stack
5665 // separately, because both the "real fullscreen" opaque window and the one for the docked
5666 // stack can control View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.
Jorim Jaggi23cc9aa2017-05-23 16:05:35 +02005667 if (mTopDockedOpaqueWindowState == null && affectsSystemUi && appWindow && attached == null
Wale Ogunwale44f036f2017-09-29 05:09:09 -07005668 && attrs.isFullscreen() && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
Jorim Jaggi86905582016-02-09 21:36:09 -08005669 mTopDockedOpaqueWindowState = win;
5670 if (mTopDockedOpaqueOrDimmingWindowState == null) {
5671 mTopDockedOpaqueOrDimmingWindowState = win;
5672 }
5673 }
5674
5675 // Also keep track of any windows that are dimming but not necessarily fullscreen in the
5676 // docked stack.
Jorim Jaggi23cc9aa2017-05-23 16:05:35 +02005677 if (mTopDockedOpaqueOrDimmingWindowState == null && affectsSystemUi && win.isDimming()
Wale Ogunwale44f036f2017-09-29 05:09:09 -07005678 && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
Jorim Jaggi86905582016-02-09 21:36:09 -08005679 mTopDockedOpaqueOrDimmingWindowState = win;
5680 }
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02005681
5682 // Take note if a window wants to acquire a sleep token.
5683 if (win.isVisibleLw() && (attrs.privateFlags & PRIVATE_FLAG_ACQUIRES_SLEEP_TOKEN) != 0
5684 && win.canAcquireSleepToken()) {
5685 mWindowSleepTokenNeeded = true;
5686 }
Jorim Jaggi86905582016-02-09 21:36:09 -08005687 }
5688
Jorim Jaggife762342016-10-13 14:33:27 +02005689 private void applyKeyguardPolicyLw(WindowState win, WindowState imeTarget) {
5690 if (canBeHiddenByKeyguardLw(win)) {
5691 if (shouldBeHiddenByKeyguard(win, imeTarget)) {
5692 win.hideLw(false /* doAnimation */);
5693 } else {
5694 win.showLw(false /* doAnimation */);
5695 }
5696 }
5697 }
5698
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08005699 /** {@inheritDoc} */
Craig Mautnerad09bcc2012-10-08 13:33:11 -07005700 @Override
Craig Mautner39834192012-09-02 07:47:24 -07005701 public int finishPostLayoutPolicyLw() {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07005702 int changes = 0;
Joe Onorato93056472010-09-10 10:30:46 -04005703 boolean topIsFullscreen = false;
Daniel Sandlere02d8082010-10-08 15:13:22 -04005704
5705 final WindowManager.LayoutParams lp = (mTopFullscreenOpaqueWindowState != null)
5706 ? mTopFullscreenOpaqueWindowState.getAttrs()
5707 : null;
5708
Jeff Brownc8018eb2012-10-29 21:33:27 -07005709 // If we are not currently showing a dream then remember the current
5710 // lockscreen state. We will use this to determine whether the dream
5711 // started while the lockscreen was showing and remember this state
5712 // while the dream is showing.
Dianne Hackborn7ad44382012-10-18 17:46:00 -07005713 if (!mShowingDream) {
Jorim Jaggi8d786932016-10-26 19:08:36 -07005714 mDreamingLockscreen = isKeyguardShowingAndNotOccluded();
Jeff Brown061ea992015-04-17 19:55:47 -07005715 if (mDreamingSleepTokenNeeded) {
5716 mDreamingSleepTokenNeeded = false;
5717 mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 0, 1).sendToTarget();
5718 }
5719 } else {
5720 if (!mDreamingSleepTokenNeeded) {
5721 mDreamingSleepTokenNeeded = true;
5722 mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 1, 1).sendToTarget();
5723 }
Dianne Hackborn7ad44382012-10-18 17:46:00 -07005724 }
5725
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005726 if (mStatusBar != null) {
Craig Mautnereda67292013-04-28 13:50:14 -07005727 if (DEBUG_LAYOUT) Slog.i(TAG, "force=" + mForceStatusBar
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07005728 + " forcefkg=" + mForceStatusBarFromKeyguard
Dianne Hackbornd70bc2f2009-10-06 23:25:51 -07005729 + " top=" + mTopFullscreenOpaqueWindowState);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07005730 boolean shouldBeTransparent = mForceStatusBarTransparent
5731 && !mForceStatusBar
5732 && !mForceStatusBarFromKeyguard;
5733 if (!shouldBeTransparent) {
5734 mStatusBarController.setShowTransparent(false /* transparent */);
5735 } else if (!mStatusBar.isVisibleLw()) {
5736 mStatusBarController.setShowTransparent(true /* transparent */);
5737 }
Adrian Roosdb1bc6b2016-04-14 17:49:43 -07005738
5739 WindowManager.LayoutParams statusBarAttrs = mStatusBar.getAttrs();
5740 boolean statusBarExpanded = statusBarAttrs.height == MATCH_PARENT
5741 && statusBarAttrs.width == MATCH_PARENT;
Selim Cinek3a49ba22017-08-10 11:17:39 -07005742 boolean topAppHidesStatusBar = topAppHidesStatusBar();
Adrian Roosdb1bc6b2016-04-14 17:49:43 -07005743 if (mForceStatusBar || mForceStatusBarFromKeyguard || mForceStatusBarTransparent
5744 || statusBarExpanded) {
Craig Mautnereda67292013-04-28 13:50:14 -07005745 if (DEBUG_LAYOUT) Slog.v(TAG, "Showing status bar: forced");
John Spurlock27735a42013-08-14 17:57:38 -04005746 if (mStatusBarController.setBarShowingLw(true)) {
5747 changes |= FINISH_LAYOUT_REDO_LAYOUT;
5748 }
Craig Mautner81defc72013-10-29 11:10:42 -07005749 // Maintain fullscreen layout until incoming animation is complete.
5750 topIsFullscreen = mTopIsFullscreen && mStatusBar.isAnimatingLw();
John Spurlockf92b6162013-11-11 15:01:16 -05005751 // Transient status bar on the lockscreen is not allowed
Jorim Jaggi2dc47c12017-05-05 17:39:58 +02005752 if ((mForceStatusBarFromKeyguard || statusBarExpanded)
5753 && mStatusBarController.isTransientShowing()) {
John Spurlockf92b6162013-11-11 15:01:16 -05005754 mStatusBarController.updateVisibilityLw(false /*transientAllowed*/,
5755 mLastSystemUiFlags, mLastSystemUiFlags);
5756 }
Adrian Roosdb1bc6b2016-04-14 17:49:43 -07005757 if (statusBarExpanded && mNavigationBar != null) {
5758 if (mNavigationBarController.setBarShowingLw(true)) {
5759 changes |= FINISH_LAYOUT_REDO_LAYOUT;
5760 }
5761 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005762 } else if (mTopFullscreenOpaqueWindowState != null) {
Selim Cinek3a49ba22017-08-10 11:17:39 -07005763 topIsFullscreen = topAppHidesStatusBar;
Joe Onorato93056472010-09-10 10:30:46 -04005764 // The subtle difference between the window for mTopFullscreenOpaqueWindowState
Mark Dolinerd0646dc2014-08-27 16:04:02 -07005765 // and mTopIsFullscreen is that mTopIsFullscreen is set only if the window
Joe Onorato93056472010-09-10 10:30:46 -04005766 // has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the
5767 // case though.
John Spurlock27735a42013-08-14 17:57:38 -04005768 if (mStatusBarController.isTransientShowing()) {
5769 if (mStatusBarController.setBarShowingLw(true)) {
John Spurlock32beb2c2013-03-11 10:16:47 -04005770 changes |= FINISH_LAYOUT_REDO_LAYOUT;
5771 }
Wale Ogunwale6e94a9e2015-10-07 15:35:49 -07005772 } else if (topIsFullscreen
Wale Ogunwale44f036f2017-09-29 05:09:09 -07005773 && !mWindowManagerInternal.isStackVisible(WINDOWING_MODE_FREEFORM)
5774 && !mWindowManagerInternal.isStackVisible(
5775 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
Craig Mautnereda67292013-04-28 13:50:14 -07005776 if (DEBUG_LAYOUT) Slog.v(TAG, "** HIDING status bar");
John Spurlock27735a42013-08-14 17:57:38 -04005777 if (mStatusBarController.setBarShowingLw(false)) {
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005778 changes |= FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnereda67292013-04-28 13:50:14 -07005779 } else {
Craig Mautnerc5a6e442013-06-05 17:22:35 -07005780 if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar already hiding");
Daniel Sandler40427442010-07-16 11:44:52 -04005781 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005782 } else {
Craig Mautnereda67292013-04-28 13:50:14 -07005783 if (DEBUG_LAYOUT) Slog.v(TAG, "** SHOWING status bar: top is not fullscreen");
John Spurlock27735a42013-08-14 17:57:38 -04005784 if (mStatusBarController.setBarShowingLw(true)) {
5785 changes |= FINISH_LAYOUT_REDO_LAYOUT;
5786 }
Selim Cinek3a49ba22017-08-10 11:17:39 -07005787 topAppHidesStatusBar = false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005788 }
5789 }
Selim Cinek3a49ba22017-08-10 11:17:39 -07005790 mStatusBarController.setTopAppHidesStatusBar(topAppHidesStatusBar);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005791 }
Daniel Sandlere02d8082010-10-08 15:13:22 -04005792
Craig Mautner81defc72013-10-29 11:10:42 -07005793 if (mTopIsFullscreen != topIsFullscreen) {
5794 if (!topIsFullscreen) {
5795 // Force another layout when status bar becomes fully shown.
5796 changes |= FINISH_LAYOUT_REDO_LAYOUT;
5797 }
5798 mTopIsFullscreen = topIsFullscreen;
5799 }
Daniel Sandlere02d8082010-10-08 15:13:22 -04005800
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07005801 if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07005802 // If the navigation bar has been hidden or shown, we need to do another
5803 // layout pass to update that window.
5804 changes |= FINISH_LAYOUT_REDO_LAYOUT;
5805 }
Joe Onorato664644d2011-01-23 17:53:23 -08005806
Jorim Jaggi77e10432016-10-26 17:43:56 -07005807 if (mShowingDream != mLastShowingDream) {
5808 mLastShowingDream = mShowingDream;
5809 mWindowManagerFuncs.notifyShowingDreamChanged();
5810 }
5811
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02005812 updateWindowSleepToken();
5813
Mike Lockwood28569302010-01-28 11:54:40 -05005814 // update since mAllowLockscreenWhenOn might have changed
5815 updateLockScreenTimeout();
Dianne Hackborn39c2d712009-09-22 11:41:31 -07005816 return changes;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005817 }
5818
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02005819 private void updateWindowSleepToken() {
5820 if (mWindowSleepTokenNeeded && !mLastWindowSleepTokenNeeded) {
5821 mHandler.removeCallbacks(mReleaseSleepTokenRunnable);
5822 mHandler.post(mAcquireSleepTokenRunnable);
5823 } else if (!mWindowSleepTokenNeeded && mLastWindowSleepTokenNeeded) {
5824 mHandler.removeCallbacks(mAcquireSleepTokenRunnable);
5825 mHandler.post(mReleaseSleepTokenRunnable);
5826 }
5827 mLastWindowSleepTokenNeeded = mWindowSleepTokenNeeded;
5828 }
5829
Jorim Jaggi380ecb82014-03-14 17:25:20 +01005830 /**
Selim Cinek3a49ba22017-08-10 11:17:39 -07005831 * @return Whether the top app should hide the statusbar based on the top fullscreen opaque
5832 * window.
5833 */
5834 private boolean topAppHidesStatusBar() {
5835 if (mTopFullscreenOpaqueWindowState == null) {
5836 return false;
5837 }
5838 final int fl = PolicyControl.getWindowFlags(null,
5839 mTopFullscreenOpaqueWindowState.getAttrs());
5840 if (localLOGV) {
Robert Carr217e7cc2018-01-31 18:08:39 -08005841 Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw());
Selim Cinek3a49ba22017-08-10 11:17:39 -07005842 Slog.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs()
5843 + " lp.flags=0x" + Integer.toHexString(fl));
5844 }
5845 return (fl & LayoutParams.FLAG_FULLSCREEN) != 0
5846 || (mLastSystemUiFlags & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
5847 }
5848
5849 /**
Jim Millerab954542014-10-10 18:21:49 -07005850 * Updates the occluded state of the Keyguard.
Jorim Jaggi380ecb82014-03-14 17:25:20 +01005851 *
Jorim Jaggi380ecb82014-03-14 17:25:20 +01005852 * @return Whether the flags have changed and we have to redo the layout.
5853 */
Jorim Jaggi9ba2e102017-04-04 12:51:03 +02005854 private boolean setKeyguardOccludedLw(boolean isOccluded, boolean force) {
Jorim Jaggife762342016-10-13 14:33:27 +02005855 if (DEBUG_KEYGUARD) Slog.d(TAG, "setKeyguardOccluded occluded=" + isOccluded);
Jorim Jaggiec7708a2017-04-10 18:47:36 -07005856 final boolean wasOccluded = mKeyguardOccluded;
5857 final boolean showing = mKeyguardDelegate.isShowing();
5858 final boolean changed = wasOccluded != isOccluded || force;
5859 if (!isOccluded && changed && showing) {
Jim Millerab954542014-10-10 18:21:49 -07005860 mKeyguardOccluded = false;
Jorim Jaggi6626f542016-08-22 13:08:44 -07005861 mKeyguardDelegate.setOccluded(false, true /* animate */);
Jorim Jaggi9ba2e102017-04-04 12:51:03 +02005862 if (mStatusBar != null) {
5863 mStatusBar.getAttrs().privateFlags |= PRIVATE_FLAG_KEYGUARD;
5864 if (!mKeyguardDelegate.hasLockscreenWallpaper()) {
5865 mStatusBar.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
5866 }
Jorim Jaggid11d1a92016-08-16 16:02:32 -07005867 }
Jorim Jaggi380ecb82014-03-14 17:25:20 +01005868 return true;
Jorim Jaggiec7708a2017-04-10 18:47:36 -07005869 } else if (isOccluded && changed && showing) {
Jim Millerab954542014-10-10 18:21:49 -07005870 mKeyguardOccluded = true;
Jorim Jaggi6626f542016-08-22 13:08:44 -07005871 mKeyguardDelegate.setOccluded(true, false /* animate */);
Jorim Jaggi9ba2e102017-04-04 12:51:03 +02005872 if (mStatusBar != null) {
5873 mStatusBar.getAttrs().privateFlags &= ~PRIVATE_FLAG_KEYGUARD;
5874 mStatusBar.getAttrs().flags &= ~FLAG_SHOW_WALLPAPER;
5875 }
Jorim Jaggi380ecb82014-03-14 17:25:20 +01005876 return true;
Jorim Jaggiec7708a2017-04-10 18:47:36 -07005877 } else if (changed) {
Adrian Roos909fe2d2016-10-12 12:03:24 -07005878 mKeyguardOccluded = isOccluded;
5879 mKeyguardDelegate.setOccluded(isOccluded, false /* animate */);
5880 return false;
Jorim Jaggi380ecb82014-03-14 17:25:20 +01005881 } else {
5882 return false;
5883 }
5884 }
5885
5886 private boolean isStatusBarKeyguard() {
5887 return mStatusBar != null
5888 && (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
5889 }
5890
Jose Lima9546b202014-07-02 17:21:51 -07005891 @Override
Dianne Hackborn08743722009-12-21 12:16:51 -08005892 public boolean allowAppAnimationsLw() {
Jorim Jaggif84e2f62018-01-16 14:17:59 +01005893 return !mShowingDream;
Dianne Hackborn08743722009-12-21 12:16:51 -08005894 }
5895
Jose Lima9546b202014-07-02 17:21:51 -07005896 @Override
Dianne Hackborndf89e652011-10-06 22:35:11 -07005897 public int focusChangedLw(WindowState lastFocus, WindowState newFocus) {
Joe Onorato664644d2011-01-23 17:53:23 -08005898 mFocusedWindow = newFocus;
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07005899 if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07005900 // If the navigation bar has been hidden or shown, we need to do another
5901 // layout pass to update that window.
5902 return FINISH_LAYOUT_REDO_LAYOUT;
5903 }
5904 return 0;
Joe Onorato664644d2011-01-23 17:53:23 -08005905 }
5906
Dianne Hackborn0ecadf72009-03-31 18:00:37 -07005907 /** {@inheritDoc} */
Jose Lima9546b202014-07-02 17:21:51 -07005908 @Override
Jeff Brown46b9ac02010-04-22 18:58:52 -07005909 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
5910 // lid changed state
Jeff Brownc458ce92012-04-30 14:58:40 -07005911 final int newLidState = lidOpen ? LID_OPEN : LID_CLOSED;
5912 if (newLidState == mLidState) {
5913 return;
5914 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07005915
Jeff Brownc458ce92012-04-30 14:58:40 -07005916 mLidState = newLidState;
5917 applyLidSwitchState();
Jeff Brown01a98dd2011-09-20 15:08:29 -07005918 updateRotation(true);
Jeff Brownc458ce92012-04-30 14:58:40 -07005919
5920 if (lidOpen) {
Dianne Hackborn280a64e2015-07-13 14:48:08 -07005921 wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromLidSwitch,
5922 "android.policy:LID");
Jeff Brownc458ce92012-04-30 14:58:40 -07005923 } else if (!mLidControlsSleep) {
Jeff Brown96307042012-07-27 15:51:34 -07005924 mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
Jeff Brown46b9ac02010-04-22 18:58:52 -07005925 }
5926 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08005927
Michael Wright3818c922014-09-02 13:59:07 -07005928 @Override
5929 public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered) {
5930 int lensCoverState = lensCovered ? CAMERA_LENS_COVERED : CAMERA_LENS_UNCOVERED;
5931 if (mCameraLensCoverState == lensCoverState) {
5932 return;
5933 }
5934 if (mCameraLensCoverState == CAMERA_LENS_COVERED &&
5935 lensCoverState == CAMERA_LENS_UNCOVERED) {
5936 Intent intent;
5937 final boolean keyguardActive = mKeyguardDelegate == null ? false :
5938 mKeyguardDelegate.isShowing();
5939 if (keyguardActive) {
5940 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE);
5941 } else {
5942 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
5943 }
Dianne Hackborn280a64e2015-07-13 14:48:08 -07005944 wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromCameraLens,
5945 "android.policy:CAMERA_COVER");
Bart Sears8b1c27c2015-03-18 23:51:02 +00005946 startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
Michael Wright3818c922014-09-02 13:59:07 -07005947 }
5948 mCameraLensCoverState = lensCoverState;
5949 }
5950
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -08005951 void setHdmiPlugged(boolean plugged) {
5952 if (mHdmiPlugged != plugged) {
5953 mHdmiPlugged = plugged;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005954 updateRotation(true, true);
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -08005955 Intent intent = new Intent(ACTION_HDMI_PLUGGED);
Joe Onoratodc100302011-01-11 17:07:41 -08005956 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -08005957 intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07005958 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -08005959 }
5960 }
5961
Joe Onoratoea495d42011-04-06 11:41:11 -07005962 void initializeHdmiState() {
Jeff Sharkey89182982017-11-01 19:02:56 -06005963 final int oldMask = StrictMode.allowThreadDiskReadsMask();
5964 try {
5965 initializeHdmiStateInternal();
5966 } finally {
5967 StrictMode.setThreadPolicyMask(oldMask);
5968 }
5969 }
5970
5971 void initializeHdmiStateInternal() {
Joe Onorato7ba631f2011-05-04 15:28:00 -07005972 boolean plugged = false;
Joe Onoratoea495d42011-04-06 11:41:11 -07005973 // watch for HDMI plug messages if the hdmi switch exists
5974 if (new File("/sys/devices/virtual/switch/hdmi/state").exists()) {
5975 mHDMIObserver.startObserving("DEVPATH=/devices/virtual/switch/hdmi");
5976
Joe Onoratoea495d42011-04-06 11:41:11 -07005977 final String filename = "/sys/class/switch/hdmi/state";
5978 FileReader reader = null;
5979 try {
5980 reader = new FileReader(filename);
5981 char[] buf = new char[15];
5982 int n = reader.read(buf);
5983 if (n > 1) {
5984 plugged = 0 != Integer.parseInt(new String(buf, 0, n-1));
5985 }
5986 } catch (IOException ex) {
5987 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex);
5988 } catch (NumberFormatException ex) {
5989 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex);
5990 } finally {
5991 if (reader != null) {
5992 try {
5993 reader.close();
5994 } catch (IOException ex) {
5995 }
Joe Onoratodc100302011-01-11 17:07:41 -08005996 }
5997 }
5998 }
Joe Onorato7ba631f2011-05-04 15:28:00 -07005999 // This dance forces the code in setHdmiPlugged to run.
6000 // Always do this so the sticky intent is stuck (to false) if there is no hdmi.
6001 mHdmiPlugged = !plugged;
6002 setHdmiPlugged(!mHdmiPlugged);
Joe Onoratodc100302011-01-11 17:07:41 -08006003 }
6004
Winson44dbe292016-03-10 14:00:14 -08006005
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006006 /** {@inheritDoc} */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006007 @Override
Jeff Brown037c33e2014-04-09 00:31:55 -07006008 public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
Jeff Brown96307042012-07-27 15:51:34 -07006009 if (!mSystemBooted) {
6010 // If we have not yet booted, don't let key events do anything.
6011 return 0;
6012 }
6013
Jeff Brown037c33e2014-04-09 00:31:55 -07006014 final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0;
Jeff Brown1f245102010-11-18 20:53:46 -08006015 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
6016 final boolean canceled = event.isCanceled();
6017 final int keyCode = event.getKeyCode();
Jeff Browne20c9e02010-10-11 14:20:19 -07006018
Jeff Brown3122e442010-10-11 23:32:49 -07006019 final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
Jeff Brown3122e442010-10-11 23:32:49 -07006020
Mike Lockwoodc72b15f2009-11-28 20:58:22 -05006021 // If screen is off then we treat the case where the keyguard is open but hidden
6022 // the same as if it were open and in front.
6023 // This will prevent any keys other than the power button from waking the screen
6024 // when the keyguard is hidden by another activity.
Jim Miller5ecd8112013-01-09 18:50:26 -08006025 final boolean keyguardActive = (mKeyguardDelegate == null ? false :
Jeff Brown037c33e2014-04-09 00:31:55 -07006026 (interactive ?
Jim Millerab954542014-10-10 18:21:49 -07006027 isKeyguardShowingAndNotOccluded() :
Jim Miller5ecd8112013-01-09 18:50:26 -08006028 mKeyguardDelegate.isShowing()));
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006029
Jeff Brown40013652012-05-16 21:22:36 -07006030 if (DEBUG_INPUT) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006031 Log.d(TAG, "interceptKeyTq keycode=" + keyCode
Jeff Brown037c33e2014-04-09 00:31:55 -07006032 + " interactive=" + interactive + " keyguardActive=" + keyguardActive
Jeff Brown26875502014-01-30 21:47:47 -08006033 + " policyFlags=" + Integer.toHexString(policyFlags));
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006034 }
6035
Jeff Brown037c33e2014-04-09 00:31:55 -07006036 // Basic policy based on interactive state.
Jeff Brown4d396052010-10-29 21:50:21 -07006037 int result;
Michael Wright337d9d22014-04-22 15:03:48 -07006038 boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0
6039 || event.isWakeKey();
Michael Wrightfc01f042014-09-08 14:12:24 -07006040 if (interactive || (isInjected && !isWakeKey)) {
RoboErikde9ba392014-09-26 12:51:01 -07006041 // When the device is interactive or the key is injected pass the
6042 // key to the application.
Jeff Brown4d396052010-10-29 21:50:21 -07006043 result = ACTION_PASS_TO_USER;
Jose Lima9546b202014-07-02 17:21:51 -07006044 isWakeKey = false;
Anthony Hugh4b13ab82016-05-17 13:03:00 -07006045
6046 if (interactive) {
6047 // If the screen is awake, but the button pressed was the one that woke the device
6048 // then don't pass it to the application
6049 if (keyCode == mPendingWakeKey && !down) {
6050 result = 0;
6051 }
6052 // Reset the pending key
6053 mPendingWakeKey = PENDING_KEY_NULL;
6054 }
6055 } else if (!interactive && shouldDispatchInputWhenNonInteractive(event)) {
Michael Wrightfc01f042014-09-08 14:12:24 -07006056 // If we're currently dozing with the screen on and the keyguard showing, pass the key
6057 // to the application but preserve its wake key status to make sure we still move
6058 // from dozing to fully interactive if we would normally go from off to fully
6059 // interactive.
6060 result = ACTION_PASS_TO_USER;
Anthony Hugh4b13ab82016-05-17 13:03:00 -07006061 // Since we're dispatching the input, reset the pending key
6062 mPendingWakeKey = PENDING_KEY_NULL;
Jeff Brown4d396052010-10-29 21:50:21 -07006063 } else {
6064 // When the screen is off and the key is not injected, determine whether
6065 // to wake the device but don't pass the key to the application.
6066 result = 0;
Jeff Brown26875502014-01-30 21:47:47 -08006067 if (isWakeKey && (!down || !isWakeKeyWhenScreenOff(keyCode))) {
6068 isWakeKey = false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006069 }
Anthony Hugh4b13ab82016-05-17 13:03:00 -07006070 // Cache the wake key on down event so we can also avoid sending the up event to the app
6071 if (isWakeKey && down) {
6072 mPendingWakeKey = keyCode;
6073 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006074 }
6075
Justin Kohd378ad72013-04-01 12:18:26 -07006076 // If the key would be handled globally, just return the result, don't worry about special
6077 // key processing.
Jeff Brown13f00f02014-10-31 14:45:50 -07006078 if (isValidGlobalKey(keyCode)
6079 && mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
Michael Wright85b1af62014-06-04 14:51:58 -07006080 if (isWakeKey) {
Dianne Hackborn280a64e2015-07-13 14:48:08 -07006081 wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
Michael Wright85b1af62014-06-04 14:51:58 -07006082 }
Justin Kohd378ad72013-04-01 12:18:26 -07006083 return result;
6084 }
6085
Matthew Ng64543e62018-02-28 17:35:10 -08006086 // Enable haptics if down and virtual key without multiple repetitions. If this is a hard
6087 // virtual key such as a navigation bar button, only vibrate if flag is enabled.
6088 final boolean isNavBarVirtKey = ((event.getFlags() & KeyEvent.FLAG_VIRTUAL_HARD_KEY) != 0);
Jeff Brownbae8e772014-06-12 19:59:45 -07006089 boolean useHapticFeedback = down
6090 && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0
Matthew Ng64543e62018-02-28 17:35:10 -08006091 && (!isNavBarVirtKey || mNavBarVirtualKeyHapticFeedbackEnabled)
Jeff Brownbae8e772014-06-12 19:59:45 -07006092 && event.getRepeatCount() == 0;
6093
Winson Chung703719b2018-04-18 17:53:15 -07006094 // Cancel any pending remote recents animations before handling the button itself. In the
6095 // case where we are going home and the recents animation has already started, just cancel
6096 // the recents animation, leaving the home stack in place for the pending start activity
6097 if (isNavBarVirtKey && !down) {
6098 boolean isHomeKey = keyCode == KeyEvent.KEYCODE_HOME;
6099 mActivityManagerInternal.cancelRecentsAnimation(!isHomeKey);
6100 }
6101
Jeff Brown4d396052010-10-29 21:50:21 -07006102 // Handle special keys.
6103 switch (keyCode) {
Anthony Hugh34f09ca2016-03-04 12:03:37 -08006104 case KeyEvent.KEYCODE_BACK: {
6105 if (down) {
Anthony Hugh96e9cc52016-07-12 15:17:24 -07006106 interceptBackKeyDown();
Anthony Hugh34f09ca2016-03-04 12:03:37 -08006107 } else {
Anthony Hugh96e9cc52016-07-12 15:17:24 -07006108 boolean handled = interceptBackKeyUp(event);
Anthony Hugh34f09ca2016-03-04 12:03:37 -08006109
Anthony Hugh96e9cc52016-07-12 15:17:24 -07006110 // Don't pass back press to app if we've already handled it via long press
Anthony Hugh34f09ca2016-03-04 12:03:37 -08006111 if (handled) {
6112 result &= ~ACTION_PASS_TO_USER;
6113 }
6114 }
6115 break;
6116 }
6117
Jeff Brown4d396052010-10-29 21:50:21 -07006118 case KeyEvent.KEYCODE_VOLUME_DOWN:
Jeff Brownb0418da2010-11-01 15:24:01 -07006119 case KeyEvent.KEYCODE_VOLUME_UP:
6120 case KeyEvent.KEYCODE_VOLUME_MUTE: {
Jeff Brownd5bb82d2011-10-12 13:57:59 -07006121 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
6122 if (down) {
Mike Digman55272862018-02-20 14:35:17 -08006123 // Any activity on the vol down button stops the ringer toggle shortcut
6124 cancelPendingRingerToggleChordAction();
6125
Jeff Brown13f00f02014-10-31 14:45:50 -07006126 if (interactive && !mScreenshotChordVolumeDownKeyTriggered
Jeff Brownd5bb82d2011-10-12 13:57:59 -07006127 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
Jeff Brown13f00f02014-10-31 14:45:50 -07006128 mScreenshotChordVolumeDownKeyTriggered = true;
6129 mScreenshotChordVolumeDownKeyTime = event.getDownTime();
6130 mScreenshotChordVolumeDownKeyConsumed = false;
Jeff Brownd5bb82d2011-10-12 13:57:59 -07006131 cancelPendingPowerKeyAction();
6132 interceptScreenshotChord();
Phil Weaverce687c52017-03-15 08:51:52 -07006133 interceptAccessibilityShortcutChord();
Jeff Brownd5bb82d2011-10-12 13:57:59 -07006134 }
6135 } else {
Jeff Brown13f00f02014-10-31 14:45:50 -07006136 mScreenshotChordVolumeDownKeyTriggered = false;
Jeff Brownd5bb82d2011-10-12 13:57:59 -07006137 cancelPendingScreenshotChordAction();
Phil Weaver106fe732016-11-22 18:18:39 -08006138 cancelPendingAccessibilityShortcutAction();
Jeff Brownd5bb82d2011-10-12 13:57:59 -07006139 }
6140 } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
6141 if (down) {
Phil Weaver106fe732016-11-22 18:18:39 -08006142 if (interactive && !mA11yShortcutChordVolumeUpKeyTriggered
Jeff Brownd5bb82d2011-10-12 13:57:59 -07006143 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
Phil Weaver106fe732016-11-22 18:18:39 -08006144 mA11yShortcutChordVolumeUpKeyTriggered = true;
6145 mA11yShortcutChordVolumeUpKeyTime = event.getDownTime();
6146 mA11yShortcutChordVolumeUpKeyConsumed = false;
Jeff Brownd5bb82d2011-10-12 13:57:59 -07006147 cancelPendingPowerKeyAction();
6148 cancelPendingScreenshotChordAction();
Mike Digman55272862018-02-20 14:35:17 -08006149 cancelPendingRingerToggleChordAction();
6150
Phil Weaverce687c52017-03-15 08:51:52 -07006151 interceptAccessibilityShortcutChord();
Mike Digman55272862018-02-20 14:35:17 -08006152 interceptRingerToggleChord();
Jeff Brownd5bb82d2011-10-12 13:57:59 -07006153 }
6154 } else {
Phil Weaver106fe732016-11-22 18:18:39 -08006155 mA11yShortcutChordVolumeUpKeyTriggered = false;
Jeff Brownd5bb82d2011-10-12 13:57:59 -07006156 cancelPendingScreenshotChordAction();
Phil Weaver106fe732016-11-22 18:18:39 -08006157 cancelPendingAccessibilityShortcutAction();
Mike Digman55272862018-02-20 14:35:17 -08006158 cancelPendingRingerToggleChordAction();
Jeff Brownd5bb82d2011-10-12 13:57:59 -07006159 }
6160 }
Jeff Brown4d396052010-10-29 21:50:21 -07006161 if (down) {
Philip Quinn4b5b3c62017-07-20 21:07:58 -07006162 sendSystemKeyToStatusBarAsync(event.getKeyCode());
6163
Tyler Gunnef9f6f92014-09-12 22:16:17 -07006164 TelecomManager telecomManager = getTelecommService();
6165 if (telecomManager != null) {
6166 if (telecomManager.isRinging()) {
Santos Cordon6848f722014-05-21 15:22:12 -07006167 // If an incoming call is ringing, either VOLUME key means
6168 // "silence ringer". We handle these keys here, rather than
6169 // in the InCallScreen, to make sure we'll respond to them
6170 // even if the InCallScreen hasn't come to the foreground yet.
6171 // Look for the DOWN event here, to agree with the "fallback"
6172 // behavior in the InCallScreen.
6173 Log.i(TAG, "interceptKeyBeforeQueueing:"
6174 + " VOLUME key-down while ringing: Silence ringer!");
Jeff Brown4d396052010-10-29 21:50:21 -07006175
Santos Cordon6848f722014-05-21 15:22:12 -07006176 // Silence the ringer. (It's safe to call this
6177 // even if the ringer has already been silenced.)
Tyler Gunnef9f6f92014-09-12 22:16:17 -07006178 telecomManager.silenceRinger();
Jeff Brown4d396052010-10-29 21:50:21 -07006179
Santos Cordon6848f722014-05-21 15:22:12 -07006180 // And *don't* pass this key thru to the current activity
6181 // (which is probably the InCallScreen.)
6182 result &= ~ACTION_PASS_TO_USER;
6183 break;
6184 }
Jeff Brown4d396052010-10-29 21:50:21 -07006185 }
Eric Laurenta9a52582017-05-10 15:16:01 -07006186 int audioMode = AudioManager.MODE_NORMAL;
6187 try {
6188 audioMode = getAudioService().getMode();
6189 } catch (Exception e) {
6190 Log.e(TAG, "Error getting AudioService in interceptKeyBeforeQueueing.", e);
6191 }
6192 boolean isInCall = (telecomManager != null && telecomManager.isInCall()) ||
6193 audioMode == AudioManager.MODE_IN_COMMUNICATION;
6194 if (isInCall && (result & ACTION_PASS_TO_USER) == 0) {
6195 // If we are in call but we decided not to pass the key to
6196 // the application, just pass it to the session service.
6197 MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(
6198 event, AudioManager.USE_DEFAULT_STREAM_TYPE, false);
6199 break;
6200 }
Jaewan Kim765487f2016-01-12 14:45:42 +09006201 }
Karthik Ravi Shankar86ecf342017-04-28 15:35:58 -07006202 if (mUseTvRouting || mHandleVolumeKeysInWM) {
6203 // Defer special key handlings to
Jaewan Kim765487f2016-01-12 14:45:42 +09006204 // {@link interceptKeyBeforeDispatching()}.
6205 result |= ACTION_PASS_TO_USER;
6206 } else if ((result & ACTION_PASS_TO_USER) == 0) {
6207 // If we aren't passing to the user and no one else
6208 // handled it send it to the session manager to
6209 // figure out.
Jaewan Kim50269362016-12-23 11:22:02 +09006210 MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(
David Linf52b6072017-04-21 18:52:18 -07006211 event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);
Jeff Brown4d396052010-10-29 21:50:21 -07006212 }
6213 break;
6214 }
6215
6216 case KeyEvent.KEYCODE_ENDCALL: {
6217 result &= ~ACTION_PASS_TO_USER;
6218 if (down) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07006219 TelecomManager telecomManager = getTelecommService();
Jeff Brown4d396052010-10-29 21:50:21 -07006220 boolean hungUp = false;
Tyler Gunnef9f6f92014-09-12 22:16:17 -07006221 if (telecomManager != null) {
6222 hungUp = telecomManager.endCall();
Jeff Brown4d396052010-10-29 21:50:21 -07006223 }
Jeff Brown13f00f02014-10-31 14:45:50 -07006224 if (interactive && !hungUp) {
6225 mEndCallKeyHandled = false;
6226 mHandler.postDelayed(mEndCallLongPress,
6227 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
6228 } else {
6229 mEndCallKeyHandled = true;
6230 }
Jeff Brown4d396052010-10-29 21:50:21 -07006231 } else {
Jeff Brown13f00f02014-10-31 14:45:50 -07006232 if (!mEndCallKeyHandled) {
6233 mHandler.removeCallbacks(mEndCallLongPress);
6234 if (!canceled) {
6235 if ((mEndcallBehavior
6236 & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) {
6237 if (goHome()) {
6238 break;
6239 }
Dianne Hackborn0041e972009-07-24 17:14:43 -07006240 }
Jeff Brown13f00f02014-10-31 14:45:50 -07006241 if ((mEndcallBehavior
6242 & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
Selim Cinekab55ba52017-08-02 16:45:51 -07006243 goToSleep(event.getEventTime(),
Jeff Brown13f00f02014-10-31 14:45:50 -07006244 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
6245 isWakeKey = false;
6246 }
Jeff Brown4d396052010-10-29 21:50:21 -07006247 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006248 }
Jeff Brown4d396052010-10-29 21:50:21 -07006249 }
6250 break;
6251 }
6252
6253 case KeyEvent.KEYCODE_POWER: {
Phil Weaver106fe732016-11-22 18:18:39 -08006254 // Any activity on the power button stops the accessibility shortcut
6255 cancelPendingAccessibilityShortcutAction();
Jeff Brown4d396052010-10-29 21:50:21 -07006256 result &= ~ACTION_PASS_TO_USER;
Jeff Brown13f00f02014-10-31 14:45:50 -07006257 isWakeKey = false; // wake-up will be handled separately
Jeff Brown4d396052010-10-29 21:50:21 -07006258 if (down) {
Jeff Brown13f00f02014-10-31 14:45:50 -07006259 interceptPowerKeyDown(event, interactive);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006260 } else {
Jeff Brown13f00f02014-10-31 14:45:50 -07006261 interceptPowerKeyUp(event, interactive, canceled);
Jeff Brown4d396052010-10-29 21:50:21 -07006262 }
6263 break;
6264 }
6265
Jim Miller07e03842016-06-22 15:18:13 -07006266 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN:
Jim Millerf4c0a132016-05-17 18:11:52 -07006267 // fall through
Jim Miller07e03842016-06-22 15:18:13 -07006268 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP:
Jim Millerf4c0a132016-05-17 18:11:52 -07006269 // fall through
Jim Miller07e03842016-06-22 15:18:13 -07006270 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT:
Jim Millerf4c0a132016-05-17 18:11:52 -07006271 // fall through
Jim Miller07e03842016-06-22 15:18:13 -07006272 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT: {
6273 result &= ~ACTION_PASS_TO_USER;
6274 interceptSystemNavigationKey(event);
Jim Millerf4c0a132016-05-17 18:11:52 -07006275 break;
6276 }
6277
Jeff Brown6212a492014-03-07 13:58:47 -08006278 case KeyEvent.KEYCODE_SLEEP: {
6279 result &= ~ACTION_PASS_TO_USER;
Filip Gruszczynskia483a1d2015-03-17 19:06:58 +00006280 isWakeKey = false;
Jeff Brownbae8e772014-06-12 19:59:45 -07006281 if (!mPowerManager.isInteractive()) {
6282 useHapticFeedback = false; // suppress feedback if already non-interactive
6283 }
Nick Vaccarob593a812015-05-15 11:23:05 -07006284 if (down) {
Siarhei Vishniakou191cf1b2017-08-17 16:17:22 -07006285 sleepPress();
Nick Vaccarob593a812015-05-15 11:23:05 -07006286 } else {
6287 sleepRelease(event.getEventTime());
6288 }
Jeff Brown6212a492014-03-07 13:58:47 -08006289 break;
6290 }
6291
Nick Armstrong-Crews56ecfcc2015-09-07 21:46:50 -07006292 case KeyEvent.KEYCODE_SOFT_SLEEP: {
6293 result &= ~ACTION_PASS_TO_USER;
6294 isWakeKey = false;
6295 if (!down) {
6296 mPowerManagerInternal.setUserInactiveOverrideFromWindowManager();
6297 }
6298 break;
6299 }
6300
Jeff Brown6212a492014-03-07 13:58:47 -08006301 case KeyEvent.KEYCODE_WAKEUP: {
6302 result &= ~ACTION_PASS_TO_USER;
Jose Lima9546b202014-07-02 17:21:51 -07006303 isWakeKey = true;
Jeff Brown6212a492014-03-07 13:58:47 -08006304 break;
6305 }
6306
Jeff Brown4d396052010-10-29 21:50:21 -07006307 case KeyEvent.KEYCODE_MEDIA_PLAY:
6308 case KeyEvent.KEYCODE_MEDIA_PAUSE:
6309 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
Jeff Brown4d396052010-10-29 21:50:21 -07006310 case KeyEvent.KEYCODE_HEADSETHOOK:
6311 case KeyEvent.KEYCODE_MUTE:
6312 case KeyEvent.KEYCODE_MEDIA_STOP:
6313 case KeyEvent.KEYCODE_MEDIA_NEXT:
6314 case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
6315 case KeyEvent.KEYCODE_MEDIA_REWIND:
6316 case KeyEvent.KEYCODE_MEDIA_RECORD:
Jaekyun Seokbfdad8e2013-07-08 13:53:21 +09006317 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
6318 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
RoboErikde9ba392014-09-26 12:51:01 -07006319 if (MediaSessionLegacyHelper.getHelper(mContext).isGlobalPriorityActive()) {
6320 // If the global session is active pass all media keys to it
6321 // instead of the active window.
6322 result &= ~ACTION_PASS_TO_USER;
6323 }
Jeff Brown4d396052010-10-29 21:50:21 -07006324 if ((result & ACTION_PASS_TO_USER) == 0) {
6325 // Only do this if we would otherwise not pass it to the user. In that
6326 // case, the PhoneWindow class will do the same thing, except it will
6327 // only do it if the showing app doesn't process the key on its own.
Jeff Brown40013652012-05-16 21:22:36 -07006328 // Note that we need to make a copy of the key event here because the
6329 // original key event will be recycled when we return.
Jeff Brown4d396052010-10-29 21:50:21 -07006330 mBroadcastWakeLock.acquire();
Jeff Brown40013652012-05-16 21:22:36 -07006331 Message msg = mHandler.obtainMessage(MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK,
6332 new KeyEvent(event));
6333 msg.setAsynchronous(true);
6334 msg.sendToTarget();
Jeff Brown4d396052010-10-29 21:50:21 -07006335 }
6336 break;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006337 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006338
Jeff Brown4d396052010-10-29 21:50:21 -07006339 case KeyEvent.KEYCODE_CALL: {
6340 if (down) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -07006341 TelecomManager telecomManager = getTelecommService();
6342 if (telecomManager != null) {
6343 if (telecomManager.isRinging()) {
Santos Cordon6848f722014-05-21 15:22:12 -07006344 Log.i(TAG, "interceptKeyBeforeQueueing:"
6345 + " CALL key-down while ringing: Answer the call!");
Tyler Gunnef9f6f92014-09-12 22:16:17 -07006346 telecomManager.acceptRingingCall();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006347
Santos Cordon6848f722014-05-21 15:22:12 -07006348 // And *don't* pass this key thru to the current activity
6349 // (which is presumably the InCallScreen.)
6350 result &= ~ACTION_PASS_TO_USER;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006351 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006352 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006353 }
Jeff Brown4d396052010-10-29 21:50:21 -07006354 break;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006355 }
Siarhei Vishniakou191cf1b2017-08-17 16:17:22 -07006356 case KeyEvent.KEYCODE_ASSIST: {
6357 final boolean longPressed = event.getRepeatCount() > 0;
6358 if (down && longPressed) {
6359 Message msg = mHandler.obtainMessage(MSG_LAUNCH_ASSIST_LONG_PRESS);
Michael Wright869a67c2014-08-26 19:33:06 -07006360 msg.setAsynchronous(true);
6361 msg.sendToTarget();
6362 }
Siarhei Vishniakou191cf1b2017-08-17 16:17:22 -07006363 if (!down && !longPressed) {
6364 Message msg = mHandler.obtainMessage(MSG_LAUNCH_ASSIST, event.getDeviceId(),
6365 0 /* unused */, null /* hint */);
6366 msg.setAsynchronous(true);
6367 msg.sendToTarget();
6368 }
6369 result &= ~ACTION_PASS_TO_USER;
6370 break;
6371 }
6372 case KeyEvent.KEYCODE_VOICE_ASSIST: {
6373 if (!down) {
6374 mBroadcastWakeLock.acquire();
6375 Message msg = mHandler.obtainMessage(MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK);
6376 msg.setAsynchronous(true);
6377 msg.sendToTarget();
6378 }
6379 result &= ~ACTION_PASS_TO_USER;
Jaewan Kim49117872016-01-19 17:24:08 +09006380 break;
6381 }
6382 case KeyEvent.KEYCODE_WINDOW: {
Michael Wright19859762017-09-18 20:57:58 +01006383 if (mShortPressOnWindowBehavior == SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE) {
Winson Chungac52f282017-03-30 14:44:52 -07006384 if (mPictureInPictureVisible) {
6385 // Consumes the key only if picture-in-picture is visible to show
6386 // picture-in-picture control menu. This gives a chance to the foreground
6387 // activity to customize PIP key behavior.
Jaewan Kimf0fd2182016-04-20 21:17:58 +09006388 if (!down) {
Winson Chungac52f282017-03-30 14:44:52 -07006389 showPictureInPictureMenu(event);
Jaewan Kimf0fd2182016-04-20 21:17:58 +09006390 }
6391 result &= ~ACTION_PASS_TO_USER;
Jaewan Kim49117872016-01-19 17:24:08 +09006392 }
Jaewan Kim49117872016-01-19 17:24:08 +09006393 }
6394 break;
Michael Wright869a67c2014-08-26 19:33:06 -07006395 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006396 }
Jeff Brown26875502014-01-30 21:47:47 -08006397
Jeff Brownbae8e772014-06-12 19:59:45 -07006398 if (useHapticFeedback) {
6399 performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
6400 }
6401
Jeff Brown26875502014-01-30 21:47:47 -08006402 if (isWakeKey) {
Dianne Hackborn280a64e2015-07-13 14:48:08 -07006403 wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
Jeff Brown26875502014-01-30 21:47:47 -08006404 }
Bryce Lee584a4452014-10-21 15:55:55 -07006405
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006406 return result;
6407 }
6408
Jeff Brown1c2e4942012-11-06 16:32:01 -08006409 /**
Jim Millerf4c0a132016-05-17 18:11:52 -07006410 * Handle statusbar expansion events.
6411 * @param event
6412 */
Jim Miller07e03842016-06-22 15:18:13 -07006413 private void interceptSystemNavigationKey(KeyEvent event) {
Phil Weaver27fcd9c2017-01-20 15:57:24 -08006414 if (event.getAction() == KeyEvent.ACTION_UP) {
6415 if (!mAccessibilityManager.isEnabled()
6416 || !mAccessibilityManager.sendFingerprintGesture(event.getKeyCode())) {
Siarhei Vishniakoue5e0d9f2018-03-05 20:09:08 -08006417 if (mSystemNavigationKeysEnabled) {
Philip Quinn4b5b3c62017-07-20 21:07:58 -07006418 sendSystemKeyToStatusBarAsync(event.getKeyCode());
Jim Millerf4c0a132016-05-17 18:11:52 -07006419 }
6420 }
6421 }
6422 }
6423
6424 /**
Philip Quinn4b5b3c62017-07-20 21:07:58 -07006425 * Notify the StatusBar that a system key was pressed.
6426 */
6427 private void sendSystemKeyToStatusBar(int keyCode) {
6428 IStatusBarService statusBar = getStatusBarService();
6429 if (statusBar != null) {
6430 try {
6431 statusBar.handleSystemKey(keyCode);
6432 } catch (RemoteException e) {
6433 // Oh well.
6434 }
6435 }
6436 }
6437
6438 /**
6439 * Notify the StatusBar that a system key was pressed without blocking the current thread.
6440 */
6441 private void sendSystemKeyToStatusBarAsync(int keyCode) {
6442 Message message = mHandler.obtainMessage(MSG_SYSTEM_KEY_PRESS, keyCode, 0);
6443 message.setAsynchronous(true);
6444 mHandler.sendMessage(message);
6445 }
6446
6447 /**
Mike Digmane14e6632018-01-11 10:43:08 -08006448 * Notify the StatusBar that system rotation suggestion has changed.
6449 */
Mike Digmane0777312018-01-19 12:41:51 -08006450 private void sendProposedRotationChangeToStatusBarInternal(int rotation, boolean isValid) {
Mike Digmane14e6632018-01-11 10:43:08 -08006451 StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
6452 if (statusBar != null) {
Mike Digmane0777312018-01-19 12:41:51 -08006453 statusBar.onProposedRotationChanged(rotation, isValid);
Mike Digmane14e6632018-01-11 10:43:08 -08006454 }
6455 }
6456
6457 /**
Jeff Brown13f00f02014-10-31 14:45:50 -07006458 * Returns true if the key can have global actions attached to it.
6459 * We reserve all power management keys for the system since they require
6460 * very careful handling.
6461 */
6462 private static boolean isValidGlobalKey(int keyCode) {
6463 switch (keyCode) {
6464 case KeyEvent.KEYCODE_POWER:
6465 case KeyEvent.KEYCODE_WAKEUP:
6466 case KeyEvent.KEYCODE_SLEEP:
6467 return false;
6468 default:
6469 return true;
6470 }
6471 }
6472
6473 /**
Jeff Brown1c2e4942012-11-06 16:32:01 -08006474 * When the screen is off we ignore some keys that might otherwise typically
6475 * be considered wake keys. We filter them out here.
6476 *
6477 * {@link KeyEvent#KEYCODE_POWER} is notably absent from this list because it
6478 * is always considered a wake key.
6479 */
6480 private boolean isWakeKeyWhenScreenOff(int keyCode) {
6481 switch (keyCode) {
6482 // ignore volume keys unless docked
6483 case KeyEvent.KEYCODE_VOLUME_UP:
6484 case KeyEvent.KEYCODE_VOLUME_DOWN:
6485 case KeyEvent.KEYCODE_VOLUME_MUTE:
6486 return mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED;
6487
6488 // ignore media and camera keys
6489 case KeyEvent.KEYCODE_MUTE:
6490 case KeyEvent.KEYCODE_HEADSETHOOK:
6491 case KeyEvent.KEYCODE_MEDIA_PLAY:
6492 case KeyEvent.KEYCODE_MEDIA_PAUSE:
6493 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
6494 case KeyEvent.KEYCODE_MEDIA_STOP:
6495 case KeyEvent.KEYCODE_MEDIA_NEXT:
6496 case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
6497 case KeyEvent.KEYCODE_MEDIA_REWIND:
6498 case KeyEvent.KEYCODE_MEDIA_RECORD:
6499 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
Jaekyun Seokbfdad8e2013-07-08 13:53:21 +09006500 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK:
Jeff Brown1c2e4942012-11-06 16:32:01 -08006501 case KeyEvent.KEYCODE_CAMERA:
6502 return false;
6503 }
6504 return true;
6505 }
6506
6507
Jeff Brown56194eb2011-03-02 19:23:13 -08006508 /** {@inheritDoc} */
6509 @Override
Michael Wright70af00a2014-09-03 19:30:20 -07006510 public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {
6511 if ((policyFlags & FLAG_WAKE) != 0) {
Dianne Hackborn280a64e2015-07-13 14:48:08 -07006512 if (wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion,
6513 "android.policy:MOTION")) {
Bryce Lee5c138322014-11-03 08:26:09 -08006514 return 0;
6515 }
Michael Wright70af00a2014-09-03 19:30:20 -07006516 }
Bryce Lee5c138322014-11-03 08:26:09 -08006517
Anthony Hugh4b13ab82016-05-17 13:03:00 -07006518 if (shouldDispatchInputWhenNonInteractive(null)) {
Michael Wright70af00a2014-09-03 19:30:20 -07006519 return ACTION_PASS_TO_USER;
6520 }
Bryce Lee5c138322014-11-03 08:26:09 -08006521
Bryce Lee812d7022014-11-10 13:33:28 -08006522 // If we have not passed the action up and we are in theater mode without dreaming,
6523 // there will be no dream to intercept the touch and wake into ambient. The device should
6524 // wake up in this case.
6525 if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) {
Dianne Hackborn280a64e2015-07-13 14:48:08 -07006526 wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotionWhenNotDreaming,
6527 "android.policy:MOTION");
Bryce Lee812d7022014-11-10 13:33:28 -08006528 }
6529
Jeff Brown037c33e2014-04-09 00:31:55 -07006530 return 0;
Jeff Brown56194eb2011-03-02 19:23:13 -08006531 }
6532
Anthony Hugh4b13ab82016-05-17 13:03:00 -07006533 private boolean shouldDispatchInputWhenNonInteractive(KeyEvent event) {
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02006534 final boolean displayOff = (mDisplay == null || mDisplay.getState() == STATE_OFF);
Wale Ogunwale6b15ea52016-04-04 07:28:27 -07006535
6536 if (displayOff && !mHasFeatureWatch) {
6537 return false;
6538 }
6539
6540 // Send events to keyguard while the screen is on and it's showing.
6541 if (isKeyguardShowingAndNotOccluded() && !displayOff) {
Bryce Lee5c138322014-11-03 08:26:09 -08006542 return true;
6543 }
6544
Anthony Hugh4b13ab82016-05-17 13:03:00 -07006545 // Watches handle BACK specially
6546 if (mHasFeatureWatch
6547 && event != null
6548 && (event.getKeyCode() == KeyEvent.KEYCODE_BACK
6549 || event.getKeyCode() == KeyEvent.KEYCODE_STEM_PRIMARY)) {
6550 return false;
6551 }
6552
Bryce Lee5c138322014-11-03 08:26:09 -08006553 // Send events to a dozing dream even if the screen is off since the dream
6554 // is in control of the state of the screen.
6555 IDreamManager dreamManager = getDreamManager();
6556
6557 try {
6558 if (dreamManager != null && dreamManager.isDreaming()) {
6559 return true;
6560 }
6561 } catch (RemoteException e) {
6562 Slog.e(TAG, "RemoteException when checking if dreaming", e);
6563 }
6564
6565 // Otherwise, consume events since the user can't see what is being
6566 // interacted with.
6567 return false;
Michael Wright70af00a2014-09-03 19:30:20 -07006568 }
6569
RoboErik001c59c2015-01-26 15:53:51 -08006570 private void dispatchDirectAudioEvent(KeyEvent event) {
6571 if (event.getAction() != KeyEvent.ACTION_DOWN) {
6572 return;
6573 }
6574 int keyCode = event.getKeyCode();
John Spurlockb94f2d62015-03-17 14:11:57 -04006575 int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND
6576 | AudioManager.FLAG_FROM_KEY;
RoboErik001c59c2015-01-26 15:53:51 -08006577 String pkgName = mContext.getOpPackageName();
6578 switch (keyCode) {
6579 case KeyEvent.KEYCODE_VOLUME_UP:
6580 try {
John Spurlockee5ad722015-03-03 16:17:21 -05006581 getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE,
John Spurlock90874332015-03-10 16:00:54 -04006582 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG);
Eric Laurenta9a52582017-05-10 15:16:01 -07006583 } catch (Exception e) {
RoboErik001c59c2015-01-26 15:53:51 -08006584 Log.e(TAG, "Error dispatching volume up in dispatchTvAudioEvent.", e);
6585 }
6586 break;
6587 case KeyEvent.KEYCODE_VOLUME_DOWN:
6588 try {
John Spurlockee5ad722015-03-03 16:17:21 -05006589 getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER,
John Spurlock90874332015-03-10 16:00:54 -04006590 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG);
Eric Laurenta9a52582017-05-10 15:16:01 -07006591 } catch (Exception e) {
RoboErik001c59c2015-01-26 15:53:51 -08006592 Log.e(TAG, "Error dispatching volume down in dispatchTvAudioEvent.", e);
6593 }
6594 break;
6595 case KeyEvent.KEYCODE_VOLUME_MUTE:
6596 try {
6597 if (event.getRepeatCount() == 0) {
John Spurlockee5ad722015-03-03 16:17:21 -05006598 getAudioService().adjustSuggestedStreamVolume(
6599 AudioManager.ADJUST_TOGGLE_MUTE,
John Spurlock90874332015-03-10 16:00:54 -04006600 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG);
RoboErik001c59c2015-01-26 15:53:51 -08006601 }
Eric Laurenta9a52582017-05-10 15:16:01 -07006602 } catch (Exception e) {
RoboErik001c59c2015-01-26 15:53:51 -08006603 Log.e(TAG, "Error dispatching mute in dispatchTvAudioEvent.", e);
6604 }
6605 break;
6606 }
6607 }
6608
Jeff Brown40013652012-05-16 21:22:36 -07006609 void dispatchMediaKeyWithWakeLock(KeyEvent event) {
6610 if (DEBUG_INPUT) {
6611 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: " + event);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006612 }
6613
Jeff Brown40013652012-05-16 21:22:36 -07006614 if (mHavePendingMediaKeyRepeatWithWakeLock) {
6615 if (DEBUG_INPUT) {
6616 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: canceled repeat");
6617 }
6618
6619 mHandler.removeMessages(MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK);
6620 mHavePendingMediaKeyRepeatWithWakeLock = false;
6621 mBroadcastWakeLock.release(); // pending repeat was holding onto the wake lock
6622 }
6623
6624 dispatchMediaKeyWithWakeLockToAudioService(event);
6625
6626 if (event.getAction() == KeyEvent.ACTION_DOWN
6627 && event.getRepeatCount() == 0) {
6628 mHavePendingMediaKeyRepeatWithWakeLock = true;
6629
6630 Message msg = mHandler.obtainMessage(
6631 MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK, event);
6632 msg.setAsynchronous(true);
6633 mHandler.sendMessageDelayed(msg, ViewConfiguration.getKeyRepeatTimeout());
6634 } else {
6635 mBroadcastWakeLock.release();
6636 }
6637 }
6638
6639 void dispatchMediaKeyRepeatWithWakeLock(KeyEvent event) {
6640 mHavePendingMediaKeyRepeatWithWakeLock = false;
6641
6642 KeyEvent repeatEvent = KeyEvent.changeTimeRepeat(event,
6643 SystemClock.uptimeMillis(), 1, event.getFlags() | KeyEvent.FLAG_LONG_PRESS);
6644 if (DEBUG_INPUT) {
6645 Slog.d(TAG, "dispatchMediaKeyRepeatWithWakeLock: " + repeatEvent);
6646 }
6647
6648 dispatchMediaKeyWithWakeLockToAudioService(repeatEvent);
6649 mBroadcastWakeLock.release();
6650 }
6651
6652 void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) {
Sudheer Shankafc46e9b2016-10-21 17:55:27 -07006653 if (mActivityManagerInternal.isSystemReady()) {
RoboErik430fc482014-06-12 15:49:20 -07006654 MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(event, true);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006655 }
6656 }
6657
Siarhei Vishniakou191cf1b2017-08-17 16:17:22 -07006658 void launchVoiceAssistWithWakeLock() {
6659 final Intent voiceIntent;
6660 if (!keyguardOn()) {
6661 voiceIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
6662 } else {
6663 IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface(
6664 ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
6665 if (dic != null) {
6666 try {
6667 dic.exitIdle("voice-search");
6668 } catch (RemoteException e) {
6669 }
Dianne Hackbornb6683c42015-06-18 17:40:33 -07006670 }
Siarhei Vishniakou191cf1b2017-08-17 16:17:22 -07006671 voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
6672 voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, true);
Dianne Hackbornb6683c42015-06-18 17:40:33 -07006673 }
Bart Sears8b1c27c2015-03-18 23:51:02 +00006674 startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF);
Michael Wright869a67c2014-08-26 19:33:06 -07006675 mBroadcastWakeLock.release();
6676 }
6677
Mike Lockwood1753f7f2009-08-24 14:49:07 -07006678 BroadcastReceiver mDockReceiver = new BroadcastReceiver() {
Craig Mautnereee29c42013-01-17 14:44:34 -08006679 @Override
Mike Lockwood1753f7f2009-08-24 14:49:07 -07006680 public void onReceive(Context context, Intent intent) {
Dianne Hackborn867ab6472010-04-29 13:28:56 -07006681 if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
6682 mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
6683 Intent.EXTRA_DOCK_STATE_UNDOCKED);
Daniel Sandler6396c722013-04-16 20:19:09 -04006684 } else {
6685 try {
6686 IUiModeManager uiModeService = IUiModeManager.Stub.asInterface(
6687 ServiceManager.getService(Context.UI_MODE_SERVICE));
6688 mUiMode = uiModeService.getCurrentModeType();
6689 } catch (RemoteException e) {
6690 }
Dianne Hackborn80fa1662009-10-07 14:02:10 -07006691 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07006692 updateRotation(true);
Craig Mautnereee29c42013-01-17 14:44:34 -08006693 synchronized (mLock) {
6694 updateOrientationListenerLp();
6695 }
Mike Lockwood1753f7f2009-08-24 14:49:07 -07006696 }
6697 };
6698
Jeff Brown6aaf2952012-10-05 16:01:08 -07006699 BroadcastReceiver mDreamReceiver = new BroadcastReceiver() {
6700 @Override
6701 public void onReceive(Context context, Intent intent) {
6702 if (Intent.ACTION_DREAMING_STARTED.equals(intent.getAction())) {
Jim Miller5ecd8112013-01-09 18:50:26 -08006703 if (mKeyguardDelegate != null) {
6704 mKeyguardDelegate.onDreamingStarted();
Jeff Brown6aaf2952012-10-05 16:01:08 -07006705 }
6706 } else if (Intent.ACTION_DREAMING_STOPPED.equals(intent.getAction())) {
Jim Miller5ecd8112013-01-09 18:50:26 -08006707 if (mKeyguardDelegate != null) {
6708 mKeyguardDelegate.onDreamingStopped();
Jeff Brown6aaf2952012-10-05 16:01:08 -07006709 }
6710 }
6711 }
6712 };
6713
Christopher Tate5e08af02012-09-21 17:17:22 -07006714 BroadcastReceiver mMultiuserReceiver = new BroadcastReceiver() {
6715 @Override
6716 public void onReceive(Context context, Intent intent) {
6717 if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
6718 // tickle the settings observer: this first ensures that we're
6719 // observing the relevant settings for the newly-active user,
6720 // and then updates our own bookkeeping based on the now-
6721 // current user.
6722 mSettingsObserver.onChange(false);
John Spurlockce479d82012-11-29 09:52:21 -05006723
6724 // force a re-application of focused window sysui visibility.
6725 // the window may never have been shown for this user
6726 // e.g. the keyguard when going through the new-user setup flow
John Spurlock04db1762013-05-13 12:46:41 -04006727 synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
John Spurlockce479d82012-11-29 09:52:21 -05006728 mLastSystemUiFlags = 0;
6729 updateSystemUiVisibilityLw();
6730 }
Christopher Tate5e08af02012-09-21 17:17:22 -07006731 }
6732 }
6733 };
6734
Adrian Roosddc8b272015-05-21 16:28:27 -07006735 private final Runnable mHiddenNavPanic = new Runnable() {
John Spurlockd9b70bd2014-02-06 17:02:44 -05006736 @Override
6737 public void run() {
Adrian Roosddc8b272015-05-21 16:28:27 -07006738 synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
6739 if (!isUserSetupComplete()) {
6740 // Swipe-up for navigation bar is disabled during setup
6741 return;
6742 }
6743 mPendingPanicGestureUptime = SystemClock.uptimeMillis();
Adrian Roos1f425902016-07-22 10:37:50 -07006744 if (!isNavBarEmpty(mLastSystemUiFlags)) {
6745 mNavigationBarController.showTransient();
6746 }
Adrian Roosddc8b272015-05-21 16:28:27 -07006747 }
John Spurlockd9b70bd2014-02-06 17:02:44 -05006748 }
6749 };
6750
John Spurlocke1f366f2013-08-05 12:22:40 -04006751 private void requestTransientBars(WindowState swipeTarget) {
John Spurlock04db1762013-05-13 12:46:41 -04006752 synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
Maurice Lam99c6e072014-04-28 18:24:28 -07006753 if (!isUserSetupComplete()) {
6754 // Swipe-up for navigation bar is disabled during setup
6755 return;
6756 }
John Spurlock27735a42013-08-14 17:57:38 -04006757 boolean sb = mStatusBarController.checkShowTransientBarLw();
Adrian Roos1f425902016-07-22 10:37:50 -07006758 boolean nb = mNavigationBarController.checkShowTransientBarLw()
6759 && !isNavBarEmpty(mLastSystemUiFlags);
John Spurlockad3e6cb2013-04-30 08:47:43 -04006760 if (sb || nb) {
Adrian Roos62b65e42015-02-25 18:05:34 +01006761 // Don't show status bar when swiping on already visible navigation bar
6762 if (!nb && swipeTarget == mNavigationBar) {
John Spurlocke1f366f2013-08-05 12:22:40 -04006763 if (DEBUG) Slog.d(TAG, "Not showing transient bar, wrong swipe target");
John Spurlockad3e6cb2013-04-30 08:47:43 -04006764 return;
6765 }
John Spurlock27735a42013-08-14 17:57:38 -04006766 if (sb) mStatusBarController.showTransient();
6767 if (nb) mNavigationBarController.showTransient();
John Spurlockf1a36642013-10-12 17:50:42 -04006768 mImmersiveModeConfirmation.confirmCurrentPrompt();
John Spurlockad3e6cb2013-04-30 08:47:43 -04006769 updateSystemUiVisibilityLw();
John Spurlock32beb2c2013-03-11 10:16:47 -04006770 }
John Spurlockad3e6cb2013-04-30 08:47:43 -04006771 }
6772 }
6773
Jeff Brown3ee549c2014-09-22 20:14:39 -07006774 // Called on the PowerManager's Notifier thread.
Jeff Brownc38c9be2012-10-04 13:16:19 -07006775 @Override
Jeff Brown416c49c2015-05-26 19:50:18 -07006776 public void startedGoingToSleep(int why) {
6777 if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")");
Selim Cinekab55ba52017-08-02 16:45:51 -07006778
Jorim Jaggif1cdf952016-04-05 21:41:06 -07006779 mGoingToSleep = true;
Selim Cinekab55ba52017-08-02 16:45:51 -07006780 mRequestedOrGoingToSleep = true;
6781
Jorim Jaggid175b6c2015-05-27 15:39:09 -07006782 if (mKeyguardDelegate != null) {
6783 mKeyguardDelegate.onStartedGoingToSleep(why);
6784 }
Jeff Brown416c49c2015-05-26 19:50:18 -07006785 }
6786
6787 // Called on the PowerManager's Notifier thread.
6788 @Override
6789 public void finishedGoingToSleep(int why) {
Dianne Hackborn74489012009-03-24 20:50:09 -07006790 EventLog.writeEvent(70000, 0);
Jeff Brown416c49c2015-05-26 19:50:18 -07006791 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")");
Chris Wren9bb290b2015-06-29 12:02:13 -04006792 MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
Jeff Brown3ee549c2014-09-22 20:14:39 -07006793
Jorim Jaggif1cdf952016-04-05 21:41:06 -07006794 mGoingToSleep = false;
Selim Cinekab55ba52017-08-02 16:45:51 -07006795 mRequestedOrGoingToSleep = false;
Jorim Jaggif1cdf952016-04-05 21:41:06 -07006796
Jeff Brown3ee549c2014-09-22 20:14:39 -07006797 // We must get this work done here because the power manager will drop
6798 // the wake lock and let the system suspend once this function returns.
The Android Open Source Project0727d222009-03-11 12:11:58 -07006799 synchronized (mLock) {
Jeff Brown3ee549c2014-09-22 20:14:39 -07006800 mAwake = false;
Jeff Browna20dda42014-05-27 20:57:24 -07006801 updateWakeGestureListenerLp();
The Android Open Source Project0727d222009-03-11 12:11:58 -07006802 updateOrientationListenerLp();
Mike Lockwood28569302010-01-28 11:54:40 -05006803 updateLockScreenTimeout();
The Android Open Source Project0727d222009-03-11 12:11:58 -07006804 }
Jeff Brown3ee549c2014-09-22 20:14:39 -07006805 if (mKeyguardDelegate != null) {
Jorim Jaggif1cdf952016-04-05 21:41:06 -07006806 mKeyguardDelegate.onFinishedGoingToSleep(why,
6807 mCameraGestureTriggeredDuringGoingToSleep);
Jeff Brown3ee549c2014-09-22 20:14:39 -07006808 }
Jorim Jaggif1cdf952016-04-05 21:41:06 -07006809 mCameraGestureTriggeredDuringGoingToSleep = false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08006810 }
6811
Jeff Brown3ee549c2014-09-22 20:14:39 -07006812 // Called on the PowerManager's Notifier thread.
Jeff Brownc38c9be2012-10-04 13:16:19 -07006813 @Override
Jeff Brown416c49c2015-05-26 19:50:18 -07006814 public void startedWakingUp() {
Dianne Hackborn74489012009-03-24 20:50:09 -07006815 EventLog.writeEvent(70000, 1);
Jeff Brown416c49c2015-05-26 19:50:18 -07006816 if (DEBUG_WAKEUP) Slog.i(TAG, "Started waking up...");
Craig Mautner8a0da012014-05-31 15:13:37 -07006817
Jeff Brown3ee549c2014-09-22 20:14:39 -07006818 // Since goToSleep performs these functions synchronously, we must
6819 // do the same here. We cannot post this work to a handler because
6820 // that might cause it to become reordered with respect to what
6821 // may happen in a future call to goToSleep.
The Android Open Source Project0727d222009-03-11 12:11:58 -07006822 synchronized (mLock) {
Jeff Brown3ee549c2014-09-22 20:14:39 -07006823 mAwake = true;
Jeff Brown3ee549c2014-09-22 20:14:39 -07006824
Jeff Browna20dda42014-05-27 20:57:24 -07006825 updateWakeGestureListenerLp();
The Android Open Source Project0727d222009-03-11 12:11:58 -07006826 updateOrientationListenerLp();
Mike Lockwood28569302010-01-28 11:54:40 -05006827 updateLockScreenTimeout();
The Android Open Source Project0727d222009-03-11 12:11:58 -07006828 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07006829
Jim Miller5ecd8112013-01-09 18:50:26 -08006830 if (mKeyguardDelegate != null) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07006831 mKeyguardDelegate.onStartedWakingUp();
Jeff Brownc38c9be2012-10-04 13:16:19 -07006832 }
Jeff Brown36c4db82014-09-19 12:05:31 -07006833 }
6834
Jeff Brown416c49c2015-05-26 19:50:18 -07006835 // Called on the PowerManager's Notifier thread.
6836 @Override
6837 public void finishedWakingUp() {
6838 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished waking up...");
Adrian Roos369907f2017-07-14 14:53:39 +02006839
6840 if (mKeyguardDelegate != null) {
6841 mKeyguardDelegate.onFinishedWakingUp();
6842 }
Jeff Brown416c49c2015-05-26 19:50:18 -07006843 }
6844
6845 private void wakeUpFromPowerKey(long eventTime) {
Dianne Hackborn280a64e2015-07-13 14:48:08 -07006846 wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey, "android.policy:POWER");
Jeff Brown416c49c2015-05-26 19:50:18 -07006847 }
6848
Dianne Hackborn280a64e2015-07-13 14:48:08 -07006849 private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, String reason) {
Bryce Leed3896842015-06-23 17:06:51 -07006850 final boolean theaterModeEnabled = isTheaterModeEnabled();
6851 if (!wakeInTheaterMode && theaterModeEnabled) {
Jeff Brown416c49c2015-05-26 19:50:18 -07006852 return false;
6853 }
6854
Bryce Leed3896842015-06-23 17:06:51 -07006855 if (theaterModeEnabled) {
6856 Settings.Global.putInt(mContext.getContentResolver(),
6857 Settings.Global.THEATER_MODE_ON, 0);
6858 }
6859
Dianne Hackborn280a64e2015-07-13 14:48:08 -07006860 mPowerManager.wakeUp(wakeTime, reason);
Jeff Brown416c49c2015-05-26 19:50:18 -07006861 return true;
6862 }
6863
Jeff Brown36c4db82014-09-19 12:05:31 -07006864 private void finishKeyguardDrawn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -07006865 synchronized (mLock) {
Jorim Jaggif3255482015-07-24 12:32:42 -07006866 if (!mScreenOnEarly || mKeyguardDrawComplete) {
Stefan Kuhne9326dc12015-06-12 09:25:32 -10006867 return; // We are not awake yet or we have already informed of this event.
Jeff Brown3ee549c2014-09-22 20:14:39 -07006868 }
6869
Jeff Brown36c4db82014-09-19 12:05:31 -07006870 mKeyguardDrawComplete = true;
Jeff Brown3ee549c2014-09-22 20:14:39 -07006871 if (mKeyguardDelegate != null) {
6872 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
6873 }
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07006874 mWindowManagerDrawComplete = false;
Jeff Brown3ee549c2014-09-22 20:14:39 -07006875 }
6876
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07006877 // ... eventually calls finishWindowsDrawn which will finalize our screen turn on
6878 // as well as enabling the orientation change logic/sensor.
6879 mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback,
6880 WAITING_FOR_DRAWN_TIMEOUT);
Jeff Brown3ee549c2014-09-22 20:14:39 -07006881 }
6882
6883 // Called on the DisplayManager's DisplayPowerController thread.
6884 @Override
6885 public void screenTurnedOff() {
6886 if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turned off...");
6887
Jeff Brown48d1b142015-06-10 16:36:03 -07006888 updateScreenOffSleepToken(true);
Jeff Brown3ee549c2014-09-22 20:14:39 -07006889 synchronized (mLock) {
6890 mScreenOnEarly = false;
6891 mScreenOnFully = false;
Jorim Jaggi95c6dae2015-07-29 15:17:23 -07006892 mKeyguardDrawComplete = false;
Jeff Brown3ee549c2014-09-22 20:14:39 -07006893 mWindowManagerDrawComplete = false;
6894 mScreenOnListener = null;
6895 updateOrientationListenerLp();
Jorim Jaggi0d210f62015-07-10 14:24:44 -07006896
6897 if (mKeyguardDelegate != null) {
6898 mKeyguardDelegate.onScreenTurnedOff();
6899 }
Jeff Brown36c4db82014-09-19 12:05:31 -07006900 }
Ruben Brunkfecb6152016-10-28 20:18:57 -07006901 reportScreenStateToVrManager(false);
Jeff Brown36c4db82014-09-19 12:05:31 -07006902 }
6903
Keun-young Park4136d2d2017-05-08 14:51:59 -07006904 private long getKeyguardDrawnTimeout() {
6905 final boolean bootCompleted =
6906 LocalServices.getService(SystemServiceManager.class).isBootCompleted();
6907 // Set longer timeout if it has not booted yet to prevent showing empty window.
6908 return bootCompleted ? 1000 : 5000;
6909 }
6910
Jeff Brown3ee549c2014-09-22 20:14:39 -07006911 // Called on the DisplayManager's DisplayPowerController thread.
Jeff Brown36c4db82014-09-19 12:05:31 -07006912 @Override
6913 public void screenTurningOn(final ScreenOnListener screenOnListener) {
Jeff Brown36c4db82014-09-19 12:05:31 -07006914 if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...");
Jeff Brown36c4db82014-09-19 12:05:31 -07006915
Jeff Brown48d1b142015-06-10 16:36:03 -07006916 updateScreenOffSleepToken(false);
Jeff Brown3ee549c2014-09-22 20:14:39 -07006917 synchronized (mLock) {
6918 mScreenOnEarly = true;
6919 mScreenOnFully = false;
Jorim Jaggi95c6dae2015-07-29 15:17:23 -07006920 mKeyguardDrawComplete = false;
Jeff Brown3ee549c2014-09-22 20:14:39 -07006921 mWindowManagerDrawComplete = false;
6922 mScreenOnListener = screenOnListener;
Jeff Brown36c4db82014-09-19 12:05:31 -07006923
eddy-sh.chen0df686d2018-02-22 18:10:21 +08006924 if (mKeyguardDelegate != null && mKeyguardDelegate.hasKeyguard()) {
Jorim Jaggia4b51bc2015-08-10 18:20:43 -07006925 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
Keun-young Park4136d2d2017-05-08 14:51:59 -07006926 mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT,
6927 getKeyguardDrawnTimeout());
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07006928 mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);
6929 } else {
6930 if (DEBUG_WAKEUP) Slog.d(TAG,
6931 "null mKeyguardDelegate: setting mKeyguardDrawComplete.");
6932 finishKeyguardDrawn();
6933 }
6934 }
Jeff Brown36c4db82014-09-19 12:05:31 -07006935 }
6936
Jorim Jaggi0d210f62015-07-10 14:24:44 -07006937 // Called on the DisplayManager's DisplayPowerController thread.
6938 @Override
6939 public void screenTurnedOn() {
6940 synchronized (mLock) {
6941 if (mKeyguardDelegate != null) {
6942 mKeyguardDelegate.onScreenTurnedOn();
6943 }
6944 }
Ruben Brunkfecb6152016-10-28 20:18:57 -07006945 reportScreenStateToVrManager(true);
6946 }
6947
Jorim Jaggi51304d72017-05-17 17:25:32 +02006948 @Override
6949 public void screenTurningOff(ScreenOffListener screenOffListener) {
6950 mWindowManagerFuncs.screenTurningOff(screenOffListener);
Adrian Roos369907f2017-07-14 14:53:39 +02006951 synchronized (mLock) {
6952 if (mKeyguardDelegate != null) {
6953 mKeyguardDelegate.onScreenTurningOff();
6954 }
6955 }
Jorim Jaggi51304d72017-05-17 17:25:32 +02006956 }
6957
Ruben Brunkfecb6152016-10-28 20:18:57 -07006958 private void reportScreenStateToVrManager(boolean isScreenOn) {
Zak Cohen732aeb02017-01-29 14:19:52 -08006959 if (mVrManagerInternal == null) {
Ruben Brunkfecb6152016-10-28 20:18:57 -07006960 return;
6961 }
Zak Cohen732aeb02017-01-29 14:19:52 -08006962 mVrManagerInternal.onScreenStateChanged(isScreenOn);
6963 }
6964
Jeff Brown36c4db82014-09-19 12:05:31 -07006965 private void finishWindowsDrawn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -07006966 synchronized (mLock) {
6967 if (!mScreenOnEarly || mWindowManagerDrawComplete) {
Stefan Kuhne9326dc12015-06-12 09:25:32 -10006968 return; // Screen is not turned on or we did already handle this case earlier.
Jeff Brown3ee549c2014-09-22 20:14:39 -07006969 }
6970
Jeff Brown36c4db82014-09-19 12:05:31 -07006971 mWindowManagerDrawComplete = true;
Jeff Brown36c4db82014-09-19 12:05:31 -07006972 }
Jeff Brown3ee549c2014-09-22 20:14:39 -07006973
6974 finishScreenTurningOn();
Jeff Brownc38c9be2012-10-04 13:16:19 -07006975 }
6976
Craig Mautner8a0da012014-05-31 15:13:37 -07006977 private void finishScreenTurningOn() {
Stefan Kuhne9326dc12015-06-12 09:25:32 -10006978 synchronized (mLock) {
6979 // We have just finished drawing screen content. Since the orientation listener
6980 // gets only installed when all windows are drawn, we try to install it again.
6981 updateOrientationListenerLp();
6982 }
Jeff Brown3ee549c2014-09-22 20:14:39 -07006983 final ScreenOnListener listener;
6984 final boolean enableScreen;
Jeff Brown36c4db82014-09-19 12:05:31 -07006985 synchronized (mLock) {
Jeff Brown3ee549c2014-09-22 20:14:39 -07006986 if (DEBUG_WAKEUP) Slog.d(TAG,
6987 "finishScreenTurningOn: mAwake=" + mAwake
6988 + ", mScreenOnEarly=" + mScreenOnEarly
6989 + ", mScreenOnFully=" + mScreenOnFully
6990 + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete
6991 + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
6992
6993 if (mScreenOnFully || !mScreenOnEarly || !mWindowManagerDrawComplete
6994 || (mAwake && !mKeyguardDrawComplete)) {
6995 return; // spurious or not ready yet
Jeff Brown36c4db82014-09-19 12:05:31 -07006996 }
6997
Jeff Brown3ee549c2014-09-22 20:14:39 -07006998 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished screen turning on...");
6999 listener = mScreenOnListener;
Craig Mautner13f6ea72014-06-23 14:57:02 -07007000 mScreenOnListener = null;
Jeff Brown3ee549c2014-09-22 20:14:39 -07007001 mScreenOnFully = true;
7002
7003 // Remember the first time we draw the keyguard so we know when we're done with
7004 // the main part of booting and can enable the screen and hide boot messages.
7005 if (!mKeyguardDrawnOnce && mAwake) {
7006 mKeyguardDrawnOnce = true;
7007 enableScreen = true;
7008 if (mBootMessageNeedsHiding) {
7009 mBootMessageNeedsHiding = false;
7010 hideBootMessages();
7011 }
7012 } else {
7013 enableScreen = false;
7014 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07007015 }
7016
Jeff Brown3ee549c2014-09-22 20:14:39 -07007017 if (listener != null) {
7018 listener.onScreenOn();
7019 }
Jeff Brown4fc45272012-10-10 18:28:14 -07007020
Jeff Brown3ee549c2014-09-22 20:14:39 -07007021 if (enableScreen) {
7022 try {
7023 mWindowManager.enableScreenIfNeeded();
7024 } catch (RemoteException unhandled) {
Jeff Brown36c4db82014-09-19 12:05:31 -07007025 }
Craig Mautnera631d492014-08-05 15:16:01 -07007026 }
7027 }
7028
7029 private void handleHideBootMessage() {
Jeff Brown3ee549c2014-09-22 20:14:39 -07007030 synchronized (mLock) {
7031 if (!mKeyguardDrawnOnce) {
7032 mBootMessageNeedsHiding = true;
7033 return; // keyguard hasn't drawn the first time yet, not done booting
7034 }
Craig Mautnera631d492014-08-05 15:16:01 -07007035 }
Jeff Brown3ee549c2014-09-22 20:14:39 -07007036
7037 if (mBootMsgDialog != null) {
7038 if (DEBUG_WAKEUP) Slog.d(TAG, "handleHideBootMessage: dismissing");
7039 mBootMsgDialog.dismiss();
7040 mBootMsgDialog = null;
Craig Mautnera631d492014-08-05 15:16:01 -07007041 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07007042 }
7043
7044 @Override
Jeff Brown3ee549c2014-09-22 20:14:39 -07007045 public boolean isScreenOn() {
Jorim Jaggi67b29d52017-06-09 18:00:00 -07007046 synchronized (mLock) {
7047 return mScreenOnEarly;
7048 }
Dianne Hackborn08743722009-12-21 12:16:51 -08007049 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07007050
Adrian Roose94c15c2017-05-09 13:17:54 -07007051 @Override
Adrian Roos7c894802017-07-19 12:25:34 +02007052 public boolean okToAnimate() {
7053 return mAwake && !mGoingToSleep;
Adrian Roose94c15c2017-05-09 13:17:54 -07007054 }
7055
Dianne Hackborn08743722009-12-21 12:16:51 -08007056 /** {@inheritDoc} */
Jose Lima9546b202014-07-02 17:21:51 -07007057 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007058 public void enableKeyguard(boolean enabled) {
Jim Miller5ecd8112013-01-09 18:50:26 -08007059 if (mKeyguardDelegate != null) {
7060 mKeyguardDelegate.setKeyguardEnabled(enabled);
Mike Lockwood3a74bd32011-08-12 13:55:22 -07007061 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007062 }
7063
7064 /** {@inheritDoc} */
Jose Lima9546b202014-07-02 17:21:51 -07007065 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007066 public void exitKeyguardSecurely(OnKeyguardExitResult callback) {
Jim Miller5ecd8112013-01-09 18:50:26 -08007067 if (mKeyguardDelegate != null) {
7068 mKeyguardDelegate.verifyUnlock(callback);
Mike Lockwood3a74bd32011-08-12 13:55:22 -07007069 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007070 }
7071
Tony Mak2c0d6dc2016-04-29 16:16:54 +01007072 @Override
7073 public boolean isKeyguardShowingAndNotOccluded() {
Jim Miller5ecd8112013-01-09 18:50:26 -08007074 if (mKeyguardDelegate == null) return false;
Jim Millerab954542014-10-10 18:21:49 -07007075 return mKeyguardDelegate.isShowing() && !mKeyguardOccluded;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007076 }
7077
Jorim Jaggife762342016-10-13 14:33:27 +02007078 @Override
7079 public boolean isKeyguardTrustedLw() {
7080 if (mKeyguardDelegate == null) return false;
7081 return mKeyguardDelegate.isTrusted();
7082 }
7083
Mike Lockwood520d8bc2011-02-18 13:23:13 -05007084 /** {@inheritDoc} */
Jose Lima9546b202014-07-02 17:21:51 -07007085 @Override
Mike Lockwood520d8bc2011-02-18 13:23:13 -05007086 public boolean isKeyguardLocked() {
7087 return keyguardOn();
7088 }
7089
7090 /** {@inheritDoc} */
Jose Lima9546b202014-07-02 17:21:51 -07007091 @Override
Jim Millere4044bb2016-05-10 18:38:25 -07007092 public boolean isKeyguardSecure(int userId) {
Jim Miller5ecd8112013-01-09 18:50:26 -08007093 if (mKeyguardDelegate == null) return false;
Jim Millere4044bb2016-05-10 18:38:25 -07007094 return mKeyguardDelegate.isSecure(userId);
Mike Lockwood520d8bc2011-02-18 13:23:13 -05007095 }
7096
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007097 /** {@inheritDoc} */
Jose Lima9546b202014-07-02 17:21:51 -07007098 @Override
Jorim Jaggife762342016-10-13 14:33:27 +02007099 public boolean isKeyguardOccluded() {
7100 if (mKeyguardDelegate == null) return false;
7101 return mKeyguardOccluded;
Adrian Roos461829d2015-06-03 14:41:18 -07007102 }
7103
Siarhei Vishniakou35fbb312017-12-13 13:48:50 -08007104 /** {@inheritDoc} */
7105 @Override
7106 public boolean inKeyguardRestrictedKeyInputMode() {
7107 if (mKeyguardDelegate == null) return false;
7108 return mKeyguardDelegate.isInputRestricted();
7109 }
7110
Jose Lima9546b202014-07-02 17:21:51 -07007111 @Override
Lucas Dupinc80c67e2017-12-04 14:29:10 -08007112 public void dismissKeyguardLw(IKeyguardDismissCallback callback, CharSequence message) {
RoboErik8a2cfc32014-05-16 11:19:38 -07007113 if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
Craig Mautnerc0d2d0a2014-10-31 16:25:15 -07007114 if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.dismissKeyguardLw");
Jorim Jaggi8d786932016-10-26 19:08:36 -07007115
7116 // ask the keyguard to prompt the user to authenticate if necessary
Lucas Dupinc80c67e2017-12-04 14:29:10 -08007117 mKeyguardDelegate.dismiss(callback, message);
Jorim Jaggi241ae102016-11-02 21:57:33 -07007118 } else if (callback != null) {
7119 try {
7120 callback.onDismissError();
7121 } catch (RemoteException e) {
7122 Slog.w(TAG, "Failed to call callback", e);
7123 }
Dianne Hackborn90c52de2011-09-23 12:57:44 -07007124 }
7125 }
7126
Jorim Jaggicff0acb2014-03-31 16:35:15 +02007127 @Override
7128 public boolean isKeyguardDrawnLw() {
7129 synchronized (mLock) {
Jeff Brown3ee549c2014-09-22 20:14:39 -07007130 return mKeyguardDrawnOnce;
Jorim Jaggicff0acb2014-03-31 16:35:15 +02007131 }
7132 }
7133
Jorim Jaggi0d674622014-05-21 01:34:15 +02007134 @Override
Jorim Jaggi77e10432016-10-26 17:43:56 -07007135 public boolean isShowingDreamLw() {
7136 return mShowingDream;
7137 }
7138
7139 @Override
Jorim Jaggie29b2db2014-05-30 23:17:03 +02007140 public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
Jorim Jaggi0d674622014-05-21 01:34:15 +02007141 if (mKeyguardDelegate != null) {
Craig Mautnerc0d2d0a2014-10-31 16:25:15 -07007142 if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.startKeyguardExitAnimation");
Jorim Jaggie29b2db2014-05-30 23:17:03 +02007143 mKeyguardDelegate.startKeyguardExitAnimation(startTime, fadeoutDuration);
Jorim Jaggi0d674622014-05-21 01:34:15 +02007144 }
7145 }
7146
Jorim Jaggi737af722015-12-31 10:42:27 +01007147 @Override
7148 public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight,
Adrian Roos11c25582018-02-19 18:06:36 +01007149 DisplayCutout displayCutout, Rect outInsets) {
Jorim Jaggi737af722015-12-31 10:42:27 +01007150 outInsets.setEmpty();
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08007151
7152 // Navigation bar and status bar.
Adrian Roos11c25582018-02-19 18:06:36 +01007153 getNonDecorInsetsLw(displayRotation, displayWidth, displayHeight, displayCutout, outInsets);
Adrian Roos22af6502018-02-22 16:57:08 +01007154 outInsets.top = Math.max(outInsets.top, mStatusBarHeightForRotation[displayRotation]);
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08007155 }
7156
7157 @Override
7158 public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight,
Adrian Roos11c25582018-02-19 18:06:36 +01007159 DisplayCutout displayCutout, Rect outInsets) {
Jorim Jaggi82c9dc92016-02-05 15:10:33 -08007160 outInsets.setEmpty();
7161
7162 // Only navigation bar
Matthew Ngca4c1a32016-12-13 16:55:09 -08007163 if (mHasNavigationBar) {
Adrian Roos85d202b2016-06-02 16:27:47 -07007164 int position = navigationBarPosition(displayWidth, displayHeight, displayRotation);
7165 if (position == NAV_BAR_BOTTOM) {
Jorim Jaggi737af722015-12-31 10:42:27 +01007166 outInsets.bottom = getNavigationBarHeight(displayRotation, mUiMode);
Adrian Roos85d202b2016-06-02 16:27:47 -07007167 } else if (position == NAV_BAR_RIGHT) {
Jorim Jaggi737af722015-12-31 10:42:27 +01007168 outInsets.right = getNavigationBarWidth(displayRotation, mUiMode);
Adrian Roos85d202b2016-06-02 16:27:47 -07007169 } else if (position == NAV_BAR_LEFT) {
7170 outInsets.left = getNavigationBarWidth(displayRotation, mUiMode);
Jorim Jaggi737af722015-12-31 10:42:27 +01007171 }
7172 }
Adrian Roos11c25582018-02-19 18:06:36 +01007173
7174 if (displayCutout != null) {
7175 outInsets.left += displayCutout.getSafeInsetLeft();
7176 outInsets.top += displayCutout.getSafeInsetTop();
7177 outInsets.right += displayCutout.getSafeInsetRight();
7178 outInsets.bottom += displayCutout.getSafeInsetBottom();
7179 }
Jorim Jaggi737af722015-12-31 10:42:27 +01007180 }
7181
Jorim Jaggi5060bd82016-02-19 17:12:19 -08007182 @Override
Jorim Jaggi0ffd49c2016-02-12 15:04:21 -08007183 public boolean isNavBarForcedShownLw(WindowState windowState) {
Jorim Jaggie5638a62016-03-25 22:57:01 -07007184 return mForceShowSystemBars;
Jorim Jaggi0ffd49c2016-02-12 15:04:21 -08007185 }
7186
7187 @Override
Andrii Kulian3a1619d2017-07-07 14:38:09 -07007188 public int getNavBarPosition() {
7189 // TODO(multi-display): Support system decor on secondary displays.
7190 return mNavigationBarPosition;
7191 }
7192
7193 @Override
Jorim Jaggi5060bd82016-02-19 17:12:19 -08007194 public boolean isDockSideAllowed(int dockSide) {
7195
7196 // We do not allow all dock sides at which the navigation bar touches the docked stack.
7197 if (!mNavigationBarCanMove) {
7198 return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT;
7199 } else {
7200 return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT;
7201 }
7202 }
7203
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007204 void sendCloseSystemWindows() {
Jorim Jaggib10e33f2015-02-04 21:57:40 +01007205 PhoneWindow.sendCloseSystemWindows(mContext, null);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007206 }
7207
7208 void sendCloseSystemWindows(String reason) {
Jorim Jaggib10e33f2015-02-04 21:57:40 +01007209 PhoneWindow.sendCloseSystemWindows(mContext, reason);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007210 }
Mitsuru Oshima831d0d92009-06-16 18:27:18 -07007211
Jeff Brown01a98dd2011-09-20 15:08:29 -07007212 @Override
Andrii Kulianef5ce1c2018-03-20 19:27:24 -07007213 public int rotationForOrientationLw(int orientation, int lastRotation, boolean defaultDisplay) {
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05007214 if (false) {
7215 Slog.v(TAG, "rotationForOrientationLw(orient="
7216 + orientation + ", last=" + lastRotation
7217 + "); user=" + mUserRotation + " "
7218 + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED)
7219 ? "USER_ROTATION_LOCKED" : "")
7220 );
7221 }
7222
Craig Mautner46ac6fa2013-08-01 10:06:34 -07007223 if (mForceDefaultOrientation) {
7224 return Surface.ROTATION_0;
7225 }
7226
The Android Open Source Project0727d222009-03-11 12:11:58 -07007227 synchronized (mLock) {
Jeff Brownc0347aa2011-09-23 17:26:09 -07007228 int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1
7229 if (sensorRotation < 0) {
Jeff Brown0f862b42012-09-27 21:11:01 -07007230 sensorRotation = lastRotation;
Jeff Brownc0347aa2011-09-23 17:26:09 -07007231 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07007232
Jeff Browndec6cf42011-11-15 14:08:20 -08007233 final int preferredRotation;
Andrii Kulianef5ce1c2018-03-20 19:27:24 -07007234 if (!defaultDisplay) {
7235 // For secondary displays we ignore things like displays sensors, docking mode and
7236 // rotation lock, and always prefer a default rotation.
7237 preferredRotation = Surface.ROTATION_0;
7238 } else if (mLidState == LID_OPEN && mLidOpenRotation >= 0) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07007239 // Ignore sensor when lid switch is open and rotation is forced.
7240 preferredRotation = mLidOpenRotation;
7241 } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR
Jeff Brownc0347aa2011-09-23 17:26:09 -07007242 && (mCarDockEnablesAccelerometer || mCarDockRotation >= 0)) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07007243 // Ignore sensor when in car dock unless explicitly enabled.
7244 // This case can override the behavior of NOSENSOR, and can also
7245 // enable 180 degree rotation while docked.
Jeff Brownc0347aa2011-09-23 17:26:09 -07007246 preferredRotation = mCarDockEnablesAccelerometer
Jeff Brown01a98dd2011-09-20 15:08:29 -07007247 ? sensorRotation : mCarDockRotation;
Jeff Brown1a693182011-11-08 14:44:16 -08007248 } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK
7249 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
7250 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
Jeff Brownc0347aa2011-09-23 17:26:09 -07007251 && (mDeskDockEnablesAccelerometer || mDeskDockRotation >= 0)) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07007252 // Ignore sensor when in desk dock unless explicitly enabled.
7253 // This case can override the behavior of NOSENSOR, and can also
7254 // enable 180 degree rotation while docked.
Jeff Brownc0347aa2011-09-23 17:26:09 -07007255 preferredRotation = mDeskDockEnablesAccelerometer
Jeff Brown01a98dd2011-09-20 15:08:29 -07007256 ? sensorRotation : mDeskDockRotation;
Jeff Brownc82c89ed2013-04-17 17:18:15 -07007257 } else if (mHdmiPlugged && mDemoHdmiRotationLock) {
7258 // Ignore sensor when plugged into HDMI when demo HDMI rotation lock enabled.
Jeff Browneb3e4b92011-12-06 19:54:24 -08007259 // Note that the dock orientation overrides the HDMI orientation.
Jeff Brownc82c89ed2013-04-17 17:18:15 -07007260 preferredRotation = mDemoHdmiRotation;
7261 } else if (mHdmiPlugged && mDockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED
7262 && mUndockedHdmiRotation >= 0) {
7263 // Ignore sensor when plugged into HDMI and an undocked orientation has
7264 // been specified in the configuration (only for legacy devices without
7265 // full multi-display support).
7266 // Note that the dock orientation overrides the HDMI orientation.
7267 preferredRotation = mUndockedHdmiRotation;
Chong Zhangae6119ff2014-11-11 18:54:39 -08007268 } else if (mDemoRotationLock) {
7269 // Ignore sensor when demo rotation lock is enabled.
7270 // Note that the dock orientation and HDMI rotation lock override this.
7271 preferredRotation = mDemoRotation;
Santos Cordon0b5d9692017-07-21 12:08:53 -07007272 } else if (mPersistentVrModeEnabled) {
7273 // While in VR, apps always prefer a portrait rotation. This does not change
7274 // any apps that explicitly set landscape, but does cause sensors be ignored,
7275 // and ignored any orientation lock that the user has set (this conditional
7276 // should remain above the ORIENTATION_LOCKED conditional below).
7277 preferredRotation = mPortraitRotation;
Dianne Hackbornb9ec1ac2013-04-10 17:34:25 -07007278 } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
7279 // Application just wants to remain locked in the last rotation.
7280 preferredRotation = lastRotation;
Jeff Brownbcdfc622014-03-06 19:13:04 -08007281 } else if (!mSupportAutoRotation) {
7282 // If we don't support auto-rotation then bail out here and ignore
7283 // the sensor and any rotation lock settings.
7284 preferredRotation = -1;
Jeff Brown207673cd2012-06-05 17:47:11 -07007285 } else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
Jeff Brown01a98dd2011-09-20 15:08:29 -07007286 && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
Dianne Hackbornb9ec1ac2013-04-10 17:34:25 -07007287 || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
7288 || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
7289 || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
7290 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER))
Jeff Brown01a98dd2011-09-20 15:08:29 -07007291 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
7292 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
7293 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
7294 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
7295 // Otherwise, use sensor only if requested by the application or enabled
7296 // by default for USER or UNSPECIFIED modes. Does not apply to NOSENSOR.
Jeff Brownd3187e32011-09-21 19:26:44 -07007297 if (mAllowAllRotations < 0) {
7298 // Can't read this during init() because the context doesn't
7299 // have display metrics at that time so we cannot determine
7300 // tablet vs. phone then.
7301 mAllowAllRotations = mContext.getResources().getBoolean(
7302 com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0;
7303 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07007304 if (sensorRotation != Surface.ROTATION_180
Jeff Brownd3187e32011-09-21 19:26:44 -07007305 || mAllowAllRotations == 1
Dianne Hackbornb9ec1ac2013-04-10 17:34:25 -07007306 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
7307 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {
Santos Cordon0b5d9692017-07-21 12:08:53 -07007308 preferredRotation = sensorRotation;
Jeff Brown01a98dd2011-09-20 15:08:29 -07007309 } else {
7310 preferredRotation = lastRotation;
7311 }
Jeff Brown207673cd2012-06-05 17:47:11 -07007312 } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
7313 && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
7314 // Apply rotation lock. Does not apply to NOSENSOR.
7315 // The idea is that the user rotation expresses a weak preference for the direction
7316 // of gravity and as NOSENSOR is never affected by gravity, then neither should
7317 // NOSENSOR be affected by rotation lock (although it will be affected by docks).
Jeff Brown4dfce202011-10-05 12:00:10 -07007318 preferredRotation = mUserRotation;
Jeff Browndec6cf42011-11-15 14:08:20 -08007319 } else {
7320 // No overriding preference.
7321 // We will do exactly what the application asked us to do.
7322 preferredRotation = -1;
Jeff Brown01a98dd2011-09-20 15:08:29 -07007323 }
7324
Dianne Hackborne5439f22010-10-02 16:53:50 -07007325 switch (orientation) {
7326 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
Jeff Browndec6cf42011-11-15 14:08:20 -08007327 // Return portrait unless overridden.
7328 if (isAnyPortrait(preferredRotation)) {
7329 return preferredRotation;
7330 }
Dianne Hackborne5439f22010-10-02 16:53:50 -07007331 return mPortraitRotation;
Dianne Hackborne5439f22010-10-02 16:53:50 -07007332
Jeff Brown01a98dd2011-09-20 15:08:29 -07007333 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
Jeff Browndec6cf42011-11-15 14:08:20 -08007334 // Return landscape unless overridden.
7335 if (isLandscapeOrSeascape(preferredRotation)) {
7336 return preferredRotation;
7337 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07007338 return mLandscapeRotation;
7339
7340 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
Jeff Browndec6cf42011-11-15 14:08:20 -08007341 // Return reverse portrait unless overridden.
7342 if (isAnyPortrait(preferredRotation)) {
7343 return preferredRotation;
7344 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07007345 return mUpsideDownRotation;
7346
7347 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
Jeff Browndec6cf42011-11-15 14:08:20 -08007348 // Return seascape unless overridden.
7349 if (isLandscapeOrSeascape(preferredRotation)) {
7350 return preferredRotation;
7351 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07007352 return mSeascapeRotation;
7353
7354 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
Dianne Hackbornb9ec1ac2013-04-10 17:34:25 -07007355 case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
Jeff Brown01a98dd2011-09-20 15:08:29 -07007356 // Return either landscape rotation.
7357 if (isLandscapeOrSeascape(preferredRotation)) {
7358 return preferredRotation;
7359 }
7360 if (isLandscapeOrSeascape(lastRotation)) {
Jeff Brown4519f072011-01-23 13:16:01 -08007361 return lastRotation;
7362 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07007363 return mLandscapeRotation;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007364
Jeff Brown01a98dd2011-09-20 15:08:29 -07007365 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
Dianne Hackbornb9ec1ac2013-04-10 17:34:25 -07007366 case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
Jeff Brown01a98dd2011-09-20 15:08:29 -07007367 // Return either portrait rotation.
7368 if (isAnyPortrait(preferredRotation)) {
7369 return preferredRotation;
7370 }
7371 if (isAnyPortrait(lastRotation)) {
7372 return lastRotation;
7373 }
7374 return mPortraitRotation;
7375
7376 default:
Jeff Brown4dfce202011-10-05 12:00:10 -07007377 // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR,
7378 // just return the preferred orientation we already calculated.
Jeff Brown01a98dd2011-09-20 15:08:29 -07007379 if (preferredRotation >= 0) {
7380 return preferredRotation;
7381 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07007382 return Surface.ROTATION_0;
Daniel Sandlere7e5ac22011-02-22 16:10:21 -05007383 }
7384 }
Steve Howarda7bfe6a2010-09-23 16:47:49 -07007385 }
7386
Jeff Brown01a98dd2011-09-20 15:08:29 -07007387 @Override
7388 public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) {
7389 switch (orientation) {
7390 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
7391 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
7392 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
7393 return isAnyPortrait(rotation);
7394
7395 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
7396 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
7397 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
7398 return isLandscapeOrSeascape(rotation);
7399
7400 default:
7401 return true;
7402 }
Steve Howarda7bfe6a2010-09-23 16:47:49 -07007403 }
7404
Jeff Brownc0347aa2011-09-23 17:26:09 -07007405 @Override
7406 public void setRotationLw(int rotation) {
7407 mOrientationListener.setCurrentRotation(rotation);
7408 }
7409
Mike Digmanbe875db2018-01-26 11:13:23 -08007410 public boolean isRotationChoicePossible(int orientation) {
Mike Digmane14e6632018-01-11 10:43:08 -08007411 // Rotation choice is only shown when the user is in locked mode.
7412 if (mUserRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) return false;
7413
Mike Digmane0777312018-01-19 12:41:51 -08007414 // We should only enable rotation choice if the rotation isn't forced by the lid, dock,
7415 // demo, hdmi, vr, etc mode
Mike Digmane14e6632018-01-11 10:43:08 -08007416
Mike Digmane0777312018-01-19 12:41:51 -08007417 // Determine if the rotation is currently forced
Mike Digmane14e6632018-01-11 10:43:08 -08007418 if (mForceDefaultOrientation) {
7419 return false; // Rotation is forced to default orientation
7420
7421 } else if (mLidState == LID_OPEN && mLidOpenRotation >= 0) {
7422 return false; // Rotation is forced mLidOpenRotation
7423
7424 } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && !mCarDockEnablesAccelerometer) {
7425 return false; // Rotation forced to mCarDockRotation
7426
7427 } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK
7428 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
7429 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
7430 && !mDeskDockEnablesAccelerometer) {
7431 return false; // Rotation forced to mDeskDockRotation
7432
7433 } else if (mHdmiPlugged && mDemoHdmiRotationLock) {
7434 return false; // Rotation forced to mDemoHdmiRotation
7435
7436 } else if (mHdmiPlugged && mDockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED
7437 && mUndockedHdmiRotation >= 0) {
7438 return false; // Rotation forced to mUndockedHdmiRotation
7439
7440 } else if (mDemoRotationLock) {
7441 return false; // Rotation forced to mDemoRotation
7442
7443 } else if (mPersistentVrModeEnabled) {
7444 return false; // Rotation forced to mPortraitRotation
7445
7446 } else if (!mSupportAutoRotation) {
7447 return false;
7448 }
7449
Mike Digmanbe875db2018-01-26 11:13:23 -08007450 // Ensure that some rotation choice is possible for the given orientation
7451 switch (orientation) {
7452 case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
7453 case ActivityInfo.SCREEN_ORIENTATION_USER:
7454 case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
7455 case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
7456 case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
7457 // NOSENSOR description is ambiguous, in reality WM ignores user choice
7458 return true;
7459 }
7460
7461 // Rotation is forced, should be controlled by system
7462 return false;
Mike Digmane0777312018-01-19 12:41:51 -08007463 }
7464
7465 public boolean isValidRotationChoice(int orientation, final int preferredRotation) {
Mike Digmanbe875db2018-01-26 11:13:23 -08007466 // Determine if the given app orientation is compatible with the provided rotation choice
Mike Digmane14e6632018-01-11 10:43:08 -08007467 switch (orientation) {
Mike Digmane14e6632018-01-11 10:43:08 -08007468 case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
7469 // Works with any of the 4 rotations
7470 return preferredRotation >= 0;
7471
Mike Digmanbe875db2018-01-26 11:13:23 -08007472 case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
7473 // It's possible for the user pref to be set at 180 because of FULL_USER. This would
7474 // make switching to USER_PORTRAIT appear at 180. Provide choice to back to portrait
7475 // but never to go to 180.
7476 return preferredRotation == mPortraitRotation;
7477
7478 case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
7479 // Works landscape or seascape
7480 return isLandscapeOrSeascape(preferredRotation);
7481
7482 case ActivityInfo.SCREEN_ORIENTATION_USER:
7483 case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
7484 // Works with any rotation except upside down
Mike Digmane14e6632018-01-11 10:43:08 -08007485 return (preferredRotation >= 0) && (preferredRotation != mUpsideDownRotation);
7486 }
Mike Digmanbe875db2018-01-26 11:13:23 -08007487
7488 return false;
Mike Digmane14e6632018-01-11 10:43:08 -08007489 }
7490
Jeff Brown01a98dd2011-09-20 15:08:29 -07007491 private boolean isLandscapeOrSeascape(int rotation) {
7492 return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
Dianne Hackborne5439f22010-10-02 16:53:50 -07007493 }
7494
Jeff Brown01a98dd2011-09-20 15:08:29 -07007495 private boolean isAnyPortrait(int rotation) {
7496 return rotation == mPortraitRotation || rotation == mUpsideDownRotation;
Dianne Hackborne5439f22010-10-02 16:53:50 -07007497 }
7498
Jose Lima9546b202014-07-02 17:21:51 -07007499 @Override
Svetoslav Ganov80943d82013-01-02 10:25:37 -08007500 public int getUserRotationMode() {
7501 return Settings.System.getIntForUser(mContext.getContentResolver(),
Brett Chabot7e55c402013-05-16 19:38:08 -07007502 Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ?
7503 WindowManagerPolicy.USER_ROTATION_FREE :
7504 WindowManagerPolicy.USER_ROTATION_LOCKED;
Svetoslav Ganov80943d82013-01-02 10:25:37 -08007505 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -04007506
7507 // User rotation: to be used when all else fails in assigning an orientation to the device
Jose Lima9546b202014-07-02 17:21:51 -07007508 @Override
Daniel Sandlerb73617d2010-08-17 00:41:00 -04007509 public void setUserRotationMode(int mode, int rot) {
7510 ContentResolver res = mContext.getContentResolver();
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05007511
7512 // mUserRotationMode and mUserRotation will be assigned by the content observer
Daniel Sandlerb73617d2010-08-17 00:41:00 -04007513 if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
Christopher Tate5e08af02012-09-21 17:17:22 -07007514 Settings.System.putIntForUser(res,
Daniel Sandlerb73617d2010-08-17 00:41:00 -04007515 Settings.System.USER_ROTATION,
Christopher Tate5e08af02012-09-21 17:17:22 -07007516 rot,
7517 UserHandle.USER_CURRENT);
7518 Settings.System.putIntForUser(res,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05007519 Settings.System.ACCELEROMETER_ROTATION,
Christopher Tate5e08af02012-09-21 17:17:22 -07007520 0,
7521 UserHandle.USER_CURRENT);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04007522 } else {
Christopher Tate5e08af02012-09-21 17:17:22 -07007523 Settings.System.putIntForUser(res,
Daniel Sandlerb73617d2010-08-17 00:41:00 -04007524 Settings.System.ACCELEROMETER_ROTATION,
Christopher Tate5e08af02012-09-21 17:17:22 -07007525 1,
7526 UserHandle.USER_CURRENT);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04007527 }
7528 }
7529
Jose Lima9546b202014-07-02 17:21:51 -07007530 @Override
Jeff Brownac143512012-04-05 18:57:33 -07007531 public void setSafeMode(boolean safeMode) {
7532 mSafeMode = safeMode;
Michael Wright33d6c082017-07-21 16:40:58 +01007533 if (safeMode) {
7534 performHapticFeedbackLw(null, HapticFeedbackConstants.SAFE_MODE_ENABLED, true);
7535 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007536 }
Craig Mautnereda67292013-04-28 13:50:14 -07007537
Dianne Hackborn181ceb52009-08-27 22:16:40 -07007538 static long[] getLongIntArray(Resources r, int resid) {
Phil Weaverb9f06122017-11-30 10:48:17 -08007539 return ArrayUtils.convertToLongArray(r.getIntArray(resid));
Dianne Hackborn181ceb52009-08-27 22:16:40 -07007540 }
Craig Mautnereda67292013-04-28 13:50:14 -07007541
Keun-young Park4136d2d2017-05-08 14:51:59 -07007542 private void bindKeyguard() {
7543 synchronized (mLock) {
7544 if (mKeyguardBound) {
7545 return;
7546 }
7547 mKeyguardBound = true;
7548 }
7549 mKeyguardDelegate.bindService(mContext);
7550 }
7551
7552 @Override
7553 public void onSystemUiStarted() {
7554 bindKeyguard();
7555 }
7556
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007557 /** {@inheritDoc} */
Craig Mautnereda67292013-04-28 13:50:14 -07007558 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007559 public void systemReady() {
Keun-young Park4136d2d2017-05-08 14:51:59 -07007560 // In normal flow, systemReady is called before other system services are ready.
7561 // So it is better not to bind keyguard here.
Mike Lockwooded8902d2013-11-15 11:01:47 -08007562 mKeyguardDelegate.onSystemReady();
7563
Zak Cohen732aeb02017-01-29 14:19:52 -08007564 mVrManagerInternal = LocalServices.getService(VrManagerInternal.class);
Santos Cordonc09d89c2017-04-13 16:12:02 -07007565 if (mVrManagerInternal != null) {
7566 mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener);
7567 }
Zak Cohen732aeb02017-01-29 14:19:52 -08007568
Michael Wright3818c922014-09-02 13:59:07 -07007569 readCameraLensCoverState();
Jeff Brown4f5fa282014-06-12 19:19:15 -07007570 updateUiMode();
Dianne Hackbornb1a79802009-09-29 15:18:31 -07007571 synchronized (mLock) {
7572 updateOrientationListenerLp();
Dianne Hackbornc777e072010-02-12 13:07:59 -08007573 mSystemReady = true;
7574 mHandler.post(new Runnable() {
Craig Mautnereda67292013-04-28 13:50:14 -07007575 @Override
Dianne Hackbornc777e072010-02-12 13:07:59 -08007576 public void run() {
7577 updateSettings();
7578 }
7579 });
Keun-young Park4136d2d2017-05-08 14:51:59 -07007580 // If this happens, for whatever reason, systemReady came later than systemBooted.
7581 // And keyguard should be already bound from systemBooted
7582 if (mSystemBooted) {
7583 mKeyguardDelegate.onBootCompleted();
Adrian Roos3542f7d2015-07-13 15:57:53 -07007584 }
7585 }
7586
Michael Wrighta4d22d72015-09-16 23:19:26 +01007587 mSystemGestures.systemReady();
Amith Yamasani02a03812016-04-22 17:32:00 -07007588 mImmersiveModeConfirmation.systemReady();
Felipe Leme5f978802017-06-08 13:01:13 -07007589
7590 mAutofillManagerInternal = LocalServices.getService(AutofillManagerInternal.class);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007591 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07007592
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07007593 /** {@inheritDoc} */
Jose Lima9546b202014-07-02 17:21:51 -07007594 @Override
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07007595 public void systemBooted() {
Keun-young Park4136d2d2017-05-08 14:51:59 -07007596 bindKeyguard();
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07007597 synchronized (mLock) {
7598 mSystemBooted = true;
Keun-young Park4136d2d2017-05-08 14:51:59 -07007599 if (mSystemReady) {
7600 mKeyguardDelegate.onBootCompleted();
7601 }
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07007602 }
Jeff Brown416c49c2015-05-26 19:50:18 -07007603 startedWakingUp();
Jeff Brown36c4db82014-09-19 12:05:31 -07007604 screenTurningOn(null);
Jorim Jaggic0496072015-08-19 15:14:52 -07007605 screenTurnedOn();
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07007606 }
7607
Keun-young Park4136d2d2017-05-08 14:51:59 -07007608 @Override
7609 public boolean canDismissBootAnimation() {
7610 synchronized (mLock) {
7611 return mKeyguardDrawComplete;
7612 }
7613 }
7614
Dianne Hackborn661cd522011-08-22 00:26:20 -07007615 ProgressDialog mBootMsgDialog = null;
7616
7617 /** {@inheritDoc} */
Jose Lima9546b202014-07-02 17:21:51 -07007618 @Override
Dianne Hackborn661cd522011-08-22 00:26:20 -07007619 public void showBootMessage(final CharSequence msg, final boolean always) {
7620 mHandler.post(new Runnable() {
7621 @Override public void run() {
7622 if (mBootMsgDialog == null) {
Craig Stout4c0cb8a2014-04-04 13:03:10 -07007623 int theme;
Dmitri Plotnikov82e6dfc2017-02-24 18:10:54 -08007624 if (mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK)) {
Craig Stout4c0cb8a2014-04-04 13:03:10 -07007625 theme = com.android.internal.R.style.Theme_Leanback_Dialog_Alert;
7626 } else {
7627 theme = 0;
7628 }
Vinod Krishnanfa8fc412014-04-18 14:35:53 -07007629
7630 mBootMsgDialog = new ProgressDialog(mContext, theme) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07007631 // This dialog will consume all events coming in to
7632 // it, to avoid it trying to do things too early in boot.
7633 @Override public boolean dispatchKeyEvent(KeyEvent event) {
7634 return true;
7635 }
7636 @Override public boolean dispatchKeyShortcutEvent(KeyEvent event) {
7637 return true;
7638 }
7639 @Override public boolean dispatchTouchEvent(MotionEvent ev) {
7640 return true;
7641 }
7642 @Override public boolean dispatchTrackballEvent(MotionEvent ev) {
7643 return true;
7644 }
7645 @Override public boolean dispatchGenericMotionEvent(MotionEvent ev) {
7646 return true;
7647 }
7648 @Override public boolean dispatchPopulateAccessibilityEvent(
7649 AccessibilityEvent event) {
7650 return true;
7651 }
7652 };
Jeff Hao9f60c082014-10-28 18:51:07 -07007653 if (mContext.getPackageManager().isUpgrade()) {
7654 mBootMsgDialog.setTitle(R.string.android_upgrading_title);
7655 } else {
7656 mBootMsgDialog.setTitle(R.string.android_start_title);
7657 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07007658 mBootMsgDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
7659 mBootMsgDialog.setIndeterminate(true);
7660 mBootMsgDialog.getWindow().setType(
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007661 WindowManager.LayoutParams.TYPE_BOOT_PROGRESS);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007662 mBootMsgDialog.getWindow().addFlags(
7663 WindowManager.LayoutParams.FLAG_DIM_BEHIND
7664 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
7665 mBootMsgDialog.getWindow().setDimAmount(1);
Dianne Hackbornd9efb952011-12-07 14:56:51 -08007666 WindowManager.LayoutParams lp = mBootMsgDialog.getWindow().getAttributes();
7667 lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
7668 mBootMsgDialog.getWindow().setAttributes(lp);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007669 mBootMsgDialog.setCancelable(false);
7670 mBootMsgDialog.show();
7671 }
7672 mBootMsgDialog.setMessage(msg);
7673 }
7674 });
7675 }
7676
7677 /** {@inheritDoc} */
Jose Lima9546b202014-07-02 17:21:51 -07007678 @Override
Dianne Hackborn661cd522011-08-22 00:26:20 -07007679 public void hideBootMessages() {
Craig Mautnera631d492014-08-05 15:16:01 -07007680 mHandler.sendEmptyMessage(MSG_HIDE_BOOT_MESSAGE);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007681 }
7682
Yoshiaki Nakae1bdfc822017-09-15 15:24:34 +09007683 @Override
7684 public void requestUserActivityNotification() {
7685 if (!mNotifyUserActivity && !mHandler.hasMessages(MSG_NOTIFY_USER_ACTIVITY)) {
7686 mNotifyUserActivity = true;
7687 }
7688 }
7689
Mike Lockwood28569302010-01-28 11:54:40 -05007690 /** {@inheritDoc} */
Jose Lima9546b202014-07-02 17:21:51 -07007691 @Override
Mike Lockwood28569302010-01-28 11:54:40 -05007692 public void userActivity() {
Dianne Hackborndf89e652011-10-06 22:35:11 -07007693 // ***************************************
7694 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
7695 // ***************************************
7696 // THIS IS CALLED FROM DEEP IN THE POWER MANAGER
7697 // WITH ITS LOCKS HELD.
7698 //
7699 // This code must be VERY careful about the locks
7700 // it acquires.
7701 // In fact, the current code acquires way too many,
7702 // and probably has lurking deadlocks.
7703
Mike Lockwood28569302010-01-28 11:54:40 -05007704 synchronized (mScreenLockTimeout) {
7705 if (mLockScreenTimerActive) {
7706 // reset the timer
7707 mHandler.removeCallbacks(mScreenLockTimeout);
7708 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
7709 }
7710 }
Yoshiaki Nakae1bdfc822017-09-15 15:24:34 +09007711
7712 if (mAwake && mNotifyUserActivity) {
7713 mHandler.sendEmptyMessageDelayed(MSG_NOTIFY_USER_ACTIVITY,
7714 USER_ACTIVITY_NOTIFICATION_DELAY);
7715 mNotifyUserActivity = false;
7716 }
Daniel Sandler0601eb72011-04-13 01:01:32 -04007717 }
7718
Adam Cohenf7522022012-10-03 20:03:18 -07007719 class ScreenLockTimeout implements Runnable {
7720 Bundle options;
7721
7722 @Override
Mike Lockwood28569302010-01-28 11:54:40 -05007723 public void run() {
7724 synchronized (this) {
7725 if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard");
Jim Miller5ecd8112013-01-09 18:50:26 -08007726 if (mKeyguardDelegate != null) {
7727 mKeyguardDelegate.doKeyguardTimeout(options);
Mike Lockwood3a74bd32011-08-12 13:55:22 -07007728 }
Mike Lockwood28569302010-01-28 11:54:40 -05007729 mLockScreenTimerActive = false;
Adam Cohenf7522022012-10-03 20:03:18 -07007730 options = null;
Mike Lockwood28569302010-01-28 11:54:40 -05007731 }
7732 }
Mike Lockwood28569302010-01-28 11:54:40 -05007733
Adam Cohenf7522022012-10-03 20:03:18 -07007734 public void setLockOptions(Bundle options) {
7735 this.options = options;
7736 }
7737 }
7738
7739 ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout();
7740
Jose Lima9546b202014-07-02 17:21:51 -07007741 @Override
Adam Cohenf7522022012-10-03 20:03:18 -07007742 public void lockNow(Bundle options) {
Jim Miller93c518e2012-01-17 15:55:31 -08007743 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
7744 mHandler.removeCallbacks(mScreenLockTimeout);
Adam Cohenf7522022012-10-03 20:03:18 -07007745 if (options != null) {
7746 // In case multiple calls are made to lockNow, we don't wipe out the options
7747 // until the runnable actually executes.
7748 mScreenLockTimeout.setLockOptions(options);
7749 }
Jim Miller93c518e2012-01-17 15:55:31 -08007750 mHandler.post(mScreenLockTimeout);
7751 }
7752
Mike Lockwood28569302010-01-28 11:54:40 -05007753 private void updateLockScreenTimeout() {
7754 synchronized (mScreenLockTimeout) {
Jeff Brown3ee549c2014-09-22 20:14:39 -07007755 boolean enable = (mAllowLockscreenWhenOn && mAwake &&
Jim Millere4044bb2016-05-10 18:38:25 -07007756 mKeyguardDelegate != null && mKeyguardDelegate.isSecure(mCurrentUserId));
Mike Lockwood28569302010-01-28 11:54:40 -05007757 if (mLockScreenTimerActive != enable) {
7758 if (enable) {
7759 if (localLOGV) Log.v(TAG, "setting lockscreen timer");
Jim Miller2967f482016-01-07 15:05:32 -08007760 mHandler.removeCallbacks(mScreenLockTimeout); // remove any pending requests
Mike Lockwood28569302010-01-28 11:54:40 -05007761 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
7762 } else {
7763 if (localLOGV) Log.v(TAG, "clearing lockscreen timer");
7764 mHandler.removeCallbacks(mScreenLockTimeout);
7765 }
7766 mLockScreenTimerActive = enable;
7767 }
7768 }
7769 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007770
David Stevens9440dc82017-03-16 19:00:20 -07007771 // TODO (multidisplay): Support multiple displays in WindowManagerPolicy.
Jeff Brown061ea992015-04-17 19:55:47 -07007772 private void updateDreamingSleepToken(boolean acquire) {
7773 if (acquire) {
7774 if (mDreamingSleepToken == null) {
David Stevens9440dc82017-03-16 19:00:20 -07007775 mDreamingSleepToken = mActivityManagerInternal.acquireSleepToken(
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02007776 "Dream", DEFAULT_DISPLAY);
Jeff Brown061ea992015-04-17 19:55:47 -07007777 }
7778 } else {
7779 if (mDreamingSleepToken != null) {
7780 mDreamingSleepToken.release();
Jeff Brown48d1b142015-06-10 16:36:03 -07007781 mDreamingSleepToken = null;
7782 }
7783 }
7784 }
7785
David Stevens9440dc82017-03-16 19:00:20 -07007786 // TODO (multidisplay): Support multiple displays in WindowManagerPolicy.
Jeff Brown48d1b142015-06-10 16:36:03 -07007787 private void updateScreenOffSleepToken(boolean acquire) {
7788 if (acquire) {
7789 if (mScreenOffSleepToken == null) {
David Stevens9440dc82017-03-16 19:00:20 -07007790 mScreenOffSleepToken = mActivityManagerInternal.acquireSleepToken(
Jorim Jaggif12ec0f2017-08-23 16:14:10 +02007791 "ScreenOff", DEFAULT_DISPLAY);
Jeff Brown48d1b142015-06-10 16:36:03 -07007792 }
7793 } else {
7794 if (mScreenOffSleepToken != null) {
7795 mScreenOffSleepToken.release();
7796 mScreenOffSleepToken = null;
Jeff Brown061ea992015-04-17 19:55:47 -07007797 }
7798 }
7799 }
7800
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007801 /** {@inheritDoc} */
Craig Mautnereda67292013-04-28 13:50:14 -07007802 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007803 public void enableScreenAfterBoot() {
7804 readLidState();
Jeff Brownc458ce92012-04-30 14:58:40 -07007805 applyLidSwitchState();
Jeff Brown01a98dd2011-09-20 15:08:29 -07007806 updateRotation(true);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007807 }
Dianne Hackbornf54c8f92009-09-19 14:03:57 -07007808
Jeff Brownc458ce92012-04-30 14:58:40 -07007809 private void applyLidSwitchState() {
Jeff Brownc458ce92012-04-30 14:58:40 -07007810 if (mLidState == LID_CLOSED && mLidControlsSleep) {
Selim Cinekab55ba52017-08-02 16:45:51 -07007811 goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH,
Jeff Brown6d8fd272014-05-20 21:24:38 -07007812 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
Edward Savage-Jones7def60d2015-11-13 13:27:03 +01007813 } else if (mLidState == LID_CLOSED && mLidControlsScreenLock) {
7814 mWindowManagerFuncs.lockDeviceNow();
Jeff Brownc458ce92012-04-30 14:58:40 -07007815 }
Jeff Browna20dda42014-05-27 20:57:24 -07007816
7817 synchronized (mLock) {
7818 updateWakeGestureListenerLp();
7819 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07007820 }
7821
Jeff Brown4f5fa282014-06-12 19:19:15 -07007822 void updateUiMode() {
7823 if (mUiModeManager == null) {
7824 mUiModeManager = IUiModeManager.Stub.asInterface(
7825 ServiceManager.getService(Context.UI_MODE_SERVICE));
7826 }
7827 try {
7828 mUiMode = mUiModeManager.getCurrentModeType();
7829 } catch (RemoteException e) {
7830 }
7831 }
7832
Jeff Brown01a98dd2011-09-20 15:08:29 -07007833 void updateRotation(boolean alwaysSendConfiguration) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007834 try {
7835 //set orientation on WindowManager
Dianne Hackbornf87d1962012-04-04 12:48:24 -07007836 mWindowManager.updateRotation(alwaysSendConfiguration, false);
7837 } catch (RemoteException e) {
7838 // Ignore
7839 }
7840 }
7841
7842 void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
7843 try {
7844 //set orientation on WindowManager
7845 mWindowManager.updateRotation(alwaysSendConfiguration, forceRelayout);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007846 } catch (RemoteException e) {
7847 // Ignore
7848 }
7849 }
7850
Daniel Sandler6396c722013-04-16 20:19:09 -04007851 /**
7852 * Return an Intent to launch the currently active dock app as home. Returns
7853 * null if the standard home should be launched, which is the case if any of the following is
7854 * true:
7855 * <ul>
7856 * <li>The device is not in either car mode or desk mode
keunyounga7710492015-09-23 11:33:58 -07007857 * <li>The device is in car mode but mEnableCarDockHomeCapture is false
Daniel Sandler6396c722013-04-16 20:19:09 -04007858 * <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false
7859 * <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME
7860 * <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME
7861 * </ul>
Craig Mautnereda67292013-04-28 13:50:14 -07007862 * @return A dock intent.
Daniel Sandler6396c722013-04-16 20:19:09 -04007863 */
7864 Intent createHomeDockIntent() {
7865 Intent intent = null;
7866
7867 // What home does is based on the mode, not the dock state. That
7868 // is, when in car mode you should be taken to car home regardless
7869 // of whether we are actually in a car dock.
7870 if (mUiMode == Configuration.UI_MODE_TYPE_CAR) {
keunyounga7710492015-09-23 11:33:58 -07007871 if (mEnableCarDockHomeCapture) {
Daniel Sandler6396c722013-04-16 20:19:09 -04007872 intent = mCarDockIntent;
7873 }
7874 } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) {
7875 if (ENABLE_DESK_DOCK_HOME_CAPTURE) {
7876 intent = mDeskDockIntent;
7877 }
Jeff Brown4f5fa282014-06-12 19:19:15 -07007878 } else if (mUiMode == Configuration.UI_MODE_TYPE_WATCH
7879 && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK
7880 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK
7881 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK)) {
7882 // Always launch dock home from home when watch is docked, if it exists.
7883 intent = mDeskDockIntent;
Zak Cohendb6ca492017-01-26 14:09:00 -08007884 } else if (mUiMode == Configuration.UI_MODE_TYPE_VR_HEADSET) {
7885 if (ENABLE_VR_HEADSET_HOME_CAPTURE) {
7886 intent = mVrHeadsetHomeIntent;
7887 }
Daniel Sandler6396c722013-04-16 20:19:09 -04007888 }
7889
7890 if (intent == null) {
7891 return null;
7892 }
7893
7894 ActivityInfo ai = null;
7895 ResolveInfo info = mContext.getPackageManager().resolveActivityAsUser(
7896 intent,
John Spurlockf56bef12013-07-09 09:51:46 -04007897 PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
Craig Mautnerd625ab22013-09-06 13:40:31 -07007898 mCurrentUserId);
Daniel Sandler6396c722013-04-16 20:19:09 -04007899 if (info != null) {
7900 ai = info.activityInfo;
7901 }
7902 if (ai != null
7903 && ai.metaData != null
7904 && ai.metaData.getBoolean(Intent.METADATA_DOCK_HOME)) {
7905 intent = new Intent(intent);
7906 intent.setClassName(ai.packageName, ai.name);
7907 return intent;
7908 }
7909
7910 return null;
7911 }
7912
Filip Gruszczynskia483a1d2015-03-17 19:06:58 +00007913 void startDockOrHome(boolean fromHomeKey, boolean awakenFromDreams) {
Winson Chung2a35e6d2018-01-13 14:27:50 -08007914 try {
7915 ActivityManager.getService().stopAppSwitches();
7916 } catch (RemoteException e) {}
7917 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
7918
Filip Gruszczynskia483a1d2015-03-17 19:06:58 +00007919 if (awakenFromDreams) {
7920 awakenDreams();
7921 }
Daniel Sandler6396c722013-04-16 20:19:09 -04007922
7923 Intent dock = createHomeDockIntent();
7924 if (dock != null) {
7925 try {
Bryce Lee01b0c5f2015-02-05 18:24:04 -08007926 if (fromHomeKey) {
7927 dock.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey);
7928 }
Bart Sears8b1c27c2015-03-18 23:51:02 +00007929 startActivityAsUser(dock, UserHandle.CURRENT);
Daniel Sandler6396c722013-04-16 20:19:09 -04007930 return;
7931 } catch (ActivityNotFoundException e) {
7932 }
7933 }
7934
Bryce Lee01b0c5f2015-02-05 18:24:04 -08007935 Intent intent;
7936
7937 if (fromHomeKey) {
7938 intent = new Intent(mHomeIntent);
7939 intent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey);
7940 } else {
7941 intent = mHomeIntent;
7942 }
7943
Bryce Lee9fc0b6f2015-03-19 21:37:45 +00007944 startActivityAsUser(intent, UserHandle.CURRENT);
Dianne Hackborn39c2d712009-09-22 11:41:31 -07007945 }
Craig Mautnereda67292013-04-28 13:50:14 -07007946
Dianne Hackborn39c2d712009-09-22 11:41:31 -07007947 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007948 * goes to the home screen
7949 * @return whether it did anything
7950 */
7951 boolean goHome() {
Bart Sears8b1c27c2015-03-18 23:51:02 +00007952 if (!isUserSetupComplete()) {
7953 Slog.i(TAG, "Not going home because user setup is in progress.");
7954 return false;
7955 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007956 if (false) {
7957 // This code always brings home to the front.
Filip Gruszczynskia483a1d2015-03-17 19:06:58 +00007958 startDockOrHome(false /*fromHomeKey*/, true /* awakenFromDreams */);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007959 } else {
7960 // This code brings home to the front or, if it is already
7961 // at the front, puts the device to sleep.
7962 try {
Wink Savilled2e6a332010-02-12 12:12:06 -08007963 if (SystemProperties.getInt("persist.sys.uts-test-mode", 0) == 1) {
7964 /// Roll back EndcallBehavior as the cupcake design to pass P1 lab entry.
7965 Log.d(TAG, "UTS-TEST-MODE");
7966 } else {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08007967 ActivityManager.getService().stopAppSwitches();
Wink Savilled2e6a332010-02-12 12:12:06 -08007968 sendCloseSystemWindows();
Daniel Sandler6396c722013-04-16 20:19:09 -04007969 Intent dock = createHomeDockIntent();
7970 if (dock != null) {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08007971 int result = ActivityManager.getService()
Daniel Sandler6396c722013-04-16 20:19:09 -04007972 .startActivityAsUser(null, null, dock,
7973 dock.resolveTypeIfNeeded(mContext.getContentResolver()),
7974 null, null, 0,
7975 ActivityManager.START_FLAG_ONLY_IF_NEEDED,
Jeff Hao1b012d32014-08-20 10:35:34 -07007976 null, null, UserHandle.USER_CURRENT);
Daniel Sandler6396c722013-04-16 20:19:09 -04007977 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) {
7978 return false;
7979 }
7980 }
Dianne Hackborn39c2d712009-09-22 11:41:31 -07007981 }
Sudheer Shankadc589ac2016-11-10 15:30:17 -08007982 int result = ActivityManager.getService()
Dianne Hackbornf265ea92013-01-31 15:00:51 -08007983 .startActivityAsUser(null, null, mHomeIntent,
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007984 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
Dianne Hackborna4972e92012-03-14 10:38:05 -07007985 null, null, 0,
7986 ActivityManager.START_FLAG_ONLY_IF_NEEDED,
Jeff Hao1b012d32014-08-20 10:35:34 -07007987 null, null, UserHandle.USER_CURRENT);
Dianne Hackborna4972e92012-03-14 10:38:05 -07007988 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007989 return false;
7990 }
7991 } catch (RemoteException ex) {
7992 // bummer, the activity manager, which is in this process, is dead
7993 }
7994 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08007995 return true;
7996 }
Craig Mautnereda67292013-04-28 13:50:14 -07007997
7998 @Override
The Android Open Source Project0727d222009-03-11 12:11:58 -07007999 public void setCurrentOrientationLw(int newOrientation) {
8000 synchronized (mLock) {
8001 if (newOrientation != mCurrentAppOrientation) {
8002 mCurrentAppOrientation = newOrientation;
8003 updateOrientationListenerLp();
8004 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08008005 }
8006 }
Amith Yamasanic33cb712010-02-10 15:21:49 -08008007
Bryce Lee584a4452014-10-21 15:55:55 -07008008 private boolean isTheaterModeEnabled() {
8009 return Settings.Global.getInt(mContext.getContentResolver(),
8010 Settings.Global.THEATER_MODE_ON, 0) == 1;
8011 }
8012
Craig Mautnereda67292013-04-28 13:50:14 -07008013 @Override
The Android Open Source Project0727d222009-03-11 12:11:58 -07008014 public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always) {
Svetoslav Ganov96179212012-10-10 14:17:45 -07008015 if (!mVibrator.hasVibrator()) {
8016 return false;
8017 }
Christopher Tate5e08af02012-09-21 17:17:22 -07008018 final boolean hapticsDisabled = Settings.System.getIntForUser(mContext.getContentResolver(),
8019 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0, UserHandle.USER_CURRENT) == 0;
Jeff Brown82379ba2014-07-25 19:03:28 -07008020 if (hapticsDisabled && !always) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08008021 return false;
8022 }
Michael Wright71216972017-01-31 18:33:54 +00008023
8024 VibrationEffect effect = getVibrationEffect(effectId);
8025 if (effect == null) {
8026 return false;
8027 }
8028
8029 int owningUid;
8030 String owningPackage;
8031 if (win != null) {
8032 owningUid = win.getOwningUid();
8033 owningPackage = win.getOwningPackage();
8034 } else {
8035 owningUid = android.os.Process.myUid();
8036 owningPackage = mContext.getOpPackageName();
8037 }
8038 mVibrator.vibrate(owningUid, owningPackage, effect, VIBRATION_ATTRIBUTES);
8039 return true;
8040 }
8041
8042 private VibrationEffect getVibrationEffect(int effectId) {
8043 long[] pattern;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08008044 switch (effectId) {
Fabrice Di Meglioeeff63a2013-08-05 12:07:24 -07008045 case HapticFeedbackConstants.CLOCK_TICK:
Alexey Kuzmin6310f402018-03-20 18:21:51 +00008046 case HapticFeedbackConstants.CONTEXT_CLICK:
Michael Wright57d94d92017-05-31 14:44:45 +01008047 return VibrationEffect.get(VibrationEffect.EFFECT_TICK);
Alexey Kuzmin6310f402018-03-20 18:21:51 +00008048 case HapticFeedbackConstants.KEYBOARD_RELEASE:
8049 case HapticFeedbackConstants.TEXT_HANDLE_MOVE:
8050 case HapticFeedbackConstants.VIRTUAL_KEY_RELEASE:
8051 case HapticFeedbackConstants.ENTRY_BUMP:
8052 case HapticFeedbackConstants.DRAG_CROSSING:
8053 case HapticFeedbackConstants.GESTURE_END:
8054 return VibrationEffect.get(VibrationEffect.EFFECT_TICK, false);
8055 case HapticFeedbackConstants.KEYBOARD_TAP: // == KEYBOARD_PRESS
8056 case HapticFeedbackConstants.VIRTUAL_KEY:
8057 case HapticFeedbackConstants.EDGE_RELEASE:
8058 case HapticFeedbackConstants.CONFIRM:
8059 case HapticFeedbackConstants.GESTURE_START:
8060 return VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
8061 case HapticFeedbackConstants.LONG_PRESS:
8062 case HapticFeedbackConstants.EDGE_SQUEEZE:
8063 return VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK);
8064 case HapticFeedbackConstants.REJECT:
8065 return VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
8066
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -07008067 case HapticFeedbackConstants.CALENDAR_DATE:
8068 pattern = mCalendarDateVibePattern;
8069 break;
Dianne Hackbornb1a79802009-09-29 15:18:31 -07008070 case HapticFeedbackConstants.SAFE_MODE_ENABLED:
Amith Yamasanic33cb712010-02-10 15:21:49 -08008071 pattern = mSafeModeEnabledVibePattern;
8072 break;
Alexey Kuzmin6310f402018-03-20 18:21:51 +00008073
Amith Yamasanic33cb712010-02-10 15:21:49 -08008074 default:
Michael Wright71216972017-01-31 18:33:54 +00008075 return null;
Dianne Hackbornf265ea92013-01-31 15:00:51 -08008076 }
Erik Wolsheimer017939e2017-05-24 11:18:25 -07008077 if (pattern.length == 0) {
8078 // No vibration
8079 return null;
8080 } else if (pattern.length == 1) {
Amith Yamasanic33cb712010-02-10 15:21:49 -08008081 // One-shot vibration
Michael Wright71216972017-01-31 18:33:54 +00008082 return VibrationEffect.createOneShot(pattern[0], VibrationEffect.DEFAULT_AMPLITUDE);
Amith Yamasanic33cb712010-02-10 15:21:49 -08008083 } else {
8084 // Pattern vibration
Michael Wright71216972017-01-31 18:33:54 +00008085 return VibrationEffect.createWaveform(pattern, -1);
Amith Yamasanic33cb712010-02-10 15:21:49 -08008086 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08008087 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07008088
8089 @Override
8090 public void keepScreenOnStartedLw() {
Daniel Sandler0601eb72011-04-13 01:01:32 -04008091 }
8092
Jeff Brownc38c9be2012-10-04 13:16:19 -07008093 @Override
8094 public void keepScreenOnStoppedLw() {
Jim Millerab954542014-10-10 18:21:49 -07008095 if (isKeyguardShowingAndNotOccluded()) {
Jim Miller25190572013-02-28 17:36:24 -08008096 mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08008097 }
8098 }
Mike Lockwoodfcb39242009-10-21 23:01:07 -04008099
Dianne Hackborndf89e652011-10-06 22:35:11 -07008100 private int updateSystemUiVisibilityLw() {
Joe Onorato664644d2011-01-23 17:53:23 -08008101 // If there is no window focused, there will be nobody to handle the events
8102 // anyway, so just hang on in whatever state we're in until things settle down.
Adrian Roosdab15162016-09-12 15:08:35 -07008103 WindowState winCandidate = mFocusedWindow != null ? mFocusedWindow
Adrian Roos53f28ec2014-10-29 17:26:12 +01008104 : mTopFullscreenOpaqueWindowState;
Adrian Roosdab15162016-09-12 15:08:35 -07008105 if (winCandidate == null) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07008106 return 0;
8107 }
Adrian Roosdab15162016-09-12 15:08:35 -07008108 if (winCandidate.getAttrs().token == mImmersiveModeConfirmation.getWindowToken()) {
8109 // The immersive mode confirmation should never affect the system bar visibility,
8110 // otherwise it will unhide the navigation bar and hide itself.
8111 winCandidate = isStatusBarKeyguard() ? mStatusBar : mTopFullscreenOpaqueWindowState;
8112 if (winCandidate == null) {
8113 return 0;
8114 }
8115 }
8116 final WindowState win = winCandidate;
Jorim Jaggife762342016-10-13 14:33:27 +02008117 if ((win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 && mKeyguardOccluded) {
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008118 // We are updating at a point where the keyguard has gotten
8119 // focus, but we were last in a state where the top window is
8120 // hiding it. This is probably because the keyguard as been
8121 // shown while the top window was displayed, so we want to ignore
8122 // it here because this is just a very transient change and it
8123 // will quickly lose focus once it correctly gets hidden.
8124 return 0;
8125 }
John Spurlock32beb2c2013-03-11 10:16:47 -04008126
John Spurlock1db8b682014-02-18 11:18:59 -05008127 int tmpVisibility = PolicyControl.getSystemUiVisibility(win, null)
Dianne Hackborne26ab702011-10-16 13:21:33 -07008128 & ~mResettingSystemUiFlags
8129 & ~mForceClearedSystemUiFlags;
John Spurlock79da8332013-09-20 12:04:47 -04008130 if (mForcingShowNavBar && win.getSurfaceLayer() < mForcingShowNavBarLayer) {
John Spurlockc6d1c602014-01-17 15:22:06 -05008131 tmpVisibility &= ~PolicyControl.adjustClearableFlags(win, View.SYSTEM_UI_CLEARABLE_FLAGS);
Dianne Hackborn891d3fb2013-01-09 18:31:37 -08008132 }
Thanh Hai Mai6c009f52015-09-01 16:27:32 -07008133
Jorim Jaggi86905582016-02-09 21:36:09 -08008134 final int fullscreenVisibility = updateLightStatusBarLw(0 /* vis */,
8135 mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState);
8136 final int dockedVisibility = updateLightStatusBarLw(0 /* vis */,
8137 mTopDockedOpaqueWindowState, mTopDockedOpaqueOrDimmingWindowState);
Wale Ogunwale68278562017-09-23 17:13:55 -07008138 mWindowManagerFuncs.getStackBounds(
8139 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, mNonDockedStackBounds);
8140 mWindowManagerFuncs.getStackBounds(
8141 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, mDockedStackBounds);
John Spurlock79da8332013-09-20 12:04:47 -04008142 final int visibility = updateSystemBarsLw(win, mLastSystemUiFlags, tmpVisibility);
John Spurlockad3e6cb2013-04-30 08:47:43 -04008143 final int diff = visibility ^ mLastSystemUiFlags;
Jorim Jaggi86905582016-02-09 21:36:09 -08008144 final int fullscreenDiff = fullscreenVisibility ^ mLastFullscreenStackSysUiFlags;
8145 final int dockedDiff = dockedVisibility ^ mLastDockedStackSysUiFlags;
John Spurlock79da8332013-09-20 12:04:47 -04008146 final boolean needsMenu = win.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);
Jorim Jaggi86905582016-02-09 21:36:09 -08008147 if (diff == 0 && fullscreenDiff == 0 && dockedDiff == 0 && mLastFocusNeedsMenu == needsMenu
8148 && mFocusedApp == win.getAppToken()
8149 && mLastNonDockedStackBounds.equals(mNonDockedStackBounds)
8150 && mLastDockedStackBounds.equals(mDockedStackBounds)) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07008151 return 0;
8152 }
Dianne Hackborne26ab702011-10-16 13:21:33 -07008153 mLastSystemUiFlags = visibility;
Jorim Jaggi86905582016-02-09 21:36:09 -08008154 mLastFullscreenStackSysUiFlags = fullscreenVisibility;
8155 mLastDockedStackSysUiFlags = dockedVisibility;
Dianne Hackborn4eff8d32011-11-10 19:38:40 -08008156 mLastFocusNeedsMenu = needsMenu;
John Spurlock79da8332013-09-20 12:04:47 -04008157 mFocusedApp = win.getAppToken();
Jorim Jaggi86905582016-02-09 21:36:09 -08008158 final Rect fullscreenStackBounds = new Rect(mNonDockedStackBounds);
8159 final Rect dockedStackBounds = new Rect(mDockedStackBounds);
Dianne Hackborndf89e652011-10-06 22:35:11 -07008160 mHandler.post(new Runnable() {
Craig Mautnereda67292013-04-28 13:50:14 -07008161 @Override
Dianne Hackborndf89e652011-10-06 22:35:11 -07008162 public void run() {
Jorim Jaggi86905582016-02-09 21:36:09 -08008163 StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
8164 if (statusbar != null) {
8165 statusbar.setSystemUiVisibility(visibility, fullscreenVisibility,
8166 dockedVisibility, 0xffffffff, fullscreenStackBounds,
8167 dockedStackBounds, win.toString());
8168 statusbar.topAppWindowChanged(needsMenu);
Joe Onorato664644d2011-01-23 17:53:23 -08008169 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07008170 }
8171 });
8172 return diff;
Joe Onorato664644d2011-01-23 17:53:23 -08008173 }
8174
Jorim Jaggi86905582016-02-09 21:36:09 -08008175 private int updateLightStatusBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming) {
Jorim Jaggiff46d4c2017-07-17 16:46:00 +02008176 final boolean onKeyguard = isStatusBarKeyguard() && !mKeyguardOccluded;
8177 final WindowState statusColorWin = onKeyguard ? mStatusBar : opaqueOrDimming;
8178 if (statusColorWin != null && (statusColorWin == opaque || onKeyguard)) {
8179 // If the top fullscreen-or-dimming window is also the top fullscreen, respect
8180 // its light flag.
8181 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
Adrian Roos0c124c62018-03-19 17:47:12 +01008182 vis |= PolicyControl.getSystemUiVisibility(statusColorWin, null)
8183 & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
Jorim Jaggiff46d4c2017-07-17 16:46:00 +02008184 } else if (statusColorWin != null && statusColorWin.isDimming()) {
8185 // Otherwise if it's dimming, clear the light flag.
8186 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
Adrian Rooscd3884d2015-02-18 17:25:23 +01008187 }
8188 return vis;
8189 }
8190
Yohei Yukawad0a66b22018-01-10 13:19:54 -08008191 @VisibleForTesting
8192 @Nullable
8193 static WindowState chooseNavigationColorWindowLw(WindowState opaque,
8194 WindowState opaqueOrDimming, WindowState imeWindow,
8195 @NavigationBarPosition int navBarPosition) {
Yohei Yukawa217844e2018-01-10 13:19:59 -08008196 // If the IME window is visible and FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS is set, then IME
8197 // window can be navigation color window.
8198 final boolean imeWindowCanNavColorWindow = imeWindow != null
8199 && imeWindow.isVisibleLw()
8200 && navBarPosition == NAV_BAR_BOTTOM
8201 && (PolicyControl.getWindowFlags(imeWindow, null)
8202 & WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
8203
8204 if (opaque != null && opaqueOrDimming == opaque) {
8205 // If the top fullscreen-or-dimming window is also the top fullscreen, respect it
8206 // unless IME window is also eligible, since currently the IME window is always show
8207 // above the opaque fullscreen app window, regardless of the IME target window.
8208 // TODO(b/31559891): Maybe we need to revisit this condition once b/31559891 is fixed.
8209 return imeWindowCanNavColorWindow ? imeWindow : opaque;
8210 }
8211
8212 if (opaqueOrDimming == null || !opaqueOrDimming.isDimming()) {
8213 // No dimming window is involved. Determine the result only with the IME window.
8214 return imeWindowCanNavColorWindow ? imeWindow : null;
8215 }
8216
8217 if (!imeWindowCanNavColorWindow) {
8218 // No IME window is involved. Determine the result only with opaqueOrDimming.
8219 return opaqueOrDimming;
8220 }
8221
8222 // The IME window and the dimming window are competing. Check if the dimming window can be
8223 // IME target or not.
8224 if (LayoutParams.mayUseInputMethod(PolicyControl.getWindowFlags(opaqueOrDimming, null))) {
8225 // The IME window is above the dimming window.
Yohei Yukawad0a66b22018-01-10 13:19:54 -08008226 return imeWindow;
Yohei Yukawab08669b2017-11-09 18:45:13 +00008227 } else {
Yohei Yukawa217844e2018-01-10 13:19:59 -08008228 // The dimming window is above the IME window.
Yohei Yukawad0a66b22018-01-10 13:19:54 -08008229 return opaqueOrDimming;
Jorim Jaggi40db0292016-06-27 17:58:03 -07008230 }
Yohei Yukawad0a66b22018-01-10 13:19:54 -08008231 }
8232
8233 @VisibleForTesting
8234 static int updateLightNavigationBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming,
8235 WindowState imeWindow, WindowState navColorWin) {
Jorim Jaggi40db0292016-06-27 17:58:03 -07008236
Yohei Yukawab08669b2017-11-09 18:45:13 +00008237 if (navColorWin != null) {
Yohei Yukawa217844e2018-01-10 13:19:59 -08008238 if (navColorWin == imeWindow || navColorWin == opaque) {
8239 // Respect the light flag.
Jorim Jaggi40db0292016-06-27 17:58:03 -07008240 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
Yohei Yukawab08669b2017-11-09 18:45:13 +00008241 vis |= PolicyControl.getSystemUiVisibility(navColorWin, null)
Jorim Jaggi40db0292016-06-27 17:58:03 -07008242 & View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
Yohei Yukawa217844e2018-01-10 13:19:59 -08008243 } else if (navColorWin == opaqueOrDimming && navColorWin.isDimming()) {
8244 // Clear the light flag for dimming window.
Jorim Jaggi40db0292016-06-27 17:58:03 -07008245 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
8246 }
8247 }
8248 return vis;
8249 }
8250
John Spurlock79da8332013-09-20 12:04:47 -04008251 private int updateSystemBarsLw(WindowState win, int oldVis, int vis) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07008252 final boolean dockedStackVisible =
8253 mWindowManagerInternal.isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
Wale Ogunwale6e94a9e2015-10-07 15:35:49 -07008254 final boolean freeformStackVisible =
Wale Ogunwale44f036f2017-09-29 05:09:09 -07008255 mWindowManagerInternal.isStackVisible(WINDOWING_MODE_FREEFORM);
Jorim Jaggi9511b0f2016-01-29 19:12:44 -08008256 final boolean resizing = mWindowManagerInternal.isDockedDividerResizing();
8257
8258 // We need to force system bars when the docked stack is visible, when the freeform stack
8259 // is visible but also when we are resizing for the transitions when docked stack
8260 // visibility changes.
Jorim Jaggi0ffd49c2016-02-12 15:04:21 -08008261 mForceShowSystemBars = dockedStackVisible || freeformStackVisible || resizing;
Yorke Lee9b2ffb32016-03-07 20:42:01 -08008262 final boolean forceOpaqueStatusBar = mForceShowSystemBars && !mForceStatusBarFromKeyguard;
Wale Ogunwale6e94a9e2015-10-07 15:35:49 -07008263
John Spurlockbd957402013-10-03 11:38:39 -04008264 // apply translucent bar vis flags
Jorim Jaggife762342016-10-13 14:33:27 +02008265 WindowState fullscreenTransWin = isStatusBarKeyguard() && !mKeyguardOccluded
Jorim Jaggi380ecb82014-03-14 17:25:20 +01008266 ? mStatusBar
John Spurlockbd957402013-10-03 11:38:39 -04008267 : mTopFullscreenOpaqueWindowState;
Jorim Jaggi8f5701b2016-04-04 18:36:02 -07008268 vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
8269 vis = mNavigationBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
8270 final int dockedVis = mStatusBarController.applyTranslucentFlagLw(
8271 mTopDockedOpaqueWindowState, 0, 0);
8272
8273 final boolean fullscreenDrawsStatusBarBackground =
Adrian Roos23df3a32018-03-15 15:41:13 +01008274 drawsStatusBarBackground(vis, mTopFullscreenOpaqueWindowState);
Jorim Jaggi8f5701b2016-04-04 18:36:02 -07008275 final boolean dockedDrawsStatusBarBackground =
Adrian Roos23df3a32018-03-15 15:41:13 +01008276 drawsStatusBarBackground(dockedVis, mTopDockedOpaqueWindowState);
John Spurlockbd957402013-10-03 11:38:39 -04008277
John Spurlock27735a42013-08-14 17:57:38 -04008278 // prevent status bar interaction from clearing certain flags
Selim Cinekf83e8242015-05-19 18:08:14 -07008279 int type = win.getAttrs().type;
8280 boolean statusBarHasFocus = type == TYPE_STATUS_BAR;
John Spurlock08ffcf52014-07-11 10:13:46 -04008281 if (statusBarHasFocus && !isStatusBarKeyguard()) {
John Spurlockad3e6cb2013-04-30 08:47:43 -04008282 int flags = View.SYSTEM_UI_FLAG_FULLSCREEN
8283 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
John Spurlockcfc359a2013-09-05 10:42:03 -04008284 | View.SYSTEM_UI_FLAG_IMMERSIVE
Jorim Jaggi73fef8d2015-02-16 17:32:28 +01008285 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
8286 | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
Jorim Jaggife762342016-10-13 14:33:27 +02008287 if (mKeyguardOccluded) {
Jorim Jaggi5cf17872014-03-26 18:31:48 +01008288 flags |= View.STATUS_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSLUCENT;
8289 }
John Spurlockbd957402013-10-03 11:38:39 -04008290 vis = (vis & ~flags) | (oldVis & flags);
John Spurlockad3e6cb2013-04-30 08:47:43 -04008291 }
John Spurlockad3e6cb2013-04-30 08:47:43 -04008292
Jorim Jaggi8f5701b2016-04-04 18:36:02 -07008293 if (fullscreenDrawsStatusBarBackground && dockedDrawsStatusBarBackground) {
8294 vis |= View.STATUS_BAR_TRANSPARENT;
8295 vis &= ~View.STATUS_BAR_TRANSLUCENT;
8296 } else if ((!areTranslucentBarsAllowed() && fullscreenTransWin != mStatusBar)
Yorke Lee9b2ffb32016-03-07 20:42:01 -08008297 || forceOpaqueStatusBar) {
8298 vis &= ~(View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT);
Alan Viverette5a0f4ec2013-10-07 15:10:29 -07008299 }
8300
Yorke Lee9b2ffb32016-03-07 20:42:01 -08008301 vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing);
Yorke Lee2e4b7322016-03-02 17:33:06 -08008302
John Spurlock27735a42013-08-14 17:57:38 -04008303 // update status bar
John Spurlockf1a36642013-10-12 17:50:42 -04008304 boolean immersiveSticky =
8305 (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
Wale Ogunwale6e94a9e2015-10-07 15:35:49 -07008306 final boolean hideStatusBarWM =
8307 mTopFullscreenOpaqueWindowState != null
8308 && (PolicyControl.getWindowFlags(mTopFullscreenOpaqueWindowState, null)
John Spurlock27735a42013-08-14 17:57:38 -04008309 & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
Wale Ogunwale6e94a9e2015-10-07 15:35:49 -07008310 final boolean hideStatusBarSysui =
John Spurlock27735a42013-08-14 17:57:38 -04008311 (vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
Wale Ogunwale6e94a9e2015-10-07 15:35:49 -07008312 final boolean hideNavBarSysui =
John Spurlockf1a36642013-10-12 17:50:42 -04008313 (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
John Spurlockad3e6cb2013-04-30 08:47:43 -04008314
Wale Ogunwale6e94a9e2015-10-07 15:35:49 -07008315 final boolean transientStatusBarAllowed = mStatusBar != null
Jorim Jaggi0ffd49c2016-02-12 15:04:21 -08008316 && (statusBarHasFocus || (!mForceShowSystemBars
Wale Ogunwale6e94a9e2015-10-07 15:35:49 -07008317 && (hideStatusBarWM || (hideStatusBarSysui && immersiveSticky))));
John Spurlock27735a42013-08-14 17:57:38 -04008318
Wale Ogunwale6e94a9e2015-10-07 15:35:49 -07008319 final boolean transientNavBarAllowed = mNavigationBar != null
Jorim Jaggi0ffd49c2016-02-12 15:04:21 -08008320 && !mForceShowSystemBars && hideNavBarSysui && immersiveSticky;
John Spurlockf1a36642013-10-12 17:50:42 -04008321
Adrian Roosddc8b272015-05-21 16:28:27 -07008322 final long now = SystemClock.uptimeMillis();
8323 final boolean pendingPanic = mPendingPanicGestureUptime != 0
8324 && now - mPendingPanicGestureUptime <= PANIC_GESTURE_EXPIRATION;
8325 if (pendingPanic && hideNavBarSysui && !isStatusBarKeyguard() && mKeyguardDrawComplete) {
8326 // The user performed the panic gesture recently, we're about to hide the bars,
8327 // we're no longer on the Keyguard and the screen is ready. We can now request the bars.
8328 mPendingPanicGestureUptime = 0;
8329 mStatusBarController.showTransient();
Adrian Roos1f425902016-07-22 10:37:50 -07008330 if (!isNavBarEmpty(vis)) {
8331 mNavigationBarController.showTransient();
8332 }
Adrian Roosddc8b272015-05-21 16:28:27 -07008333 }
8334
Wale Ogunwale6e94a9e2015-10-07 15:35:49 -07008335 final boolean denyTransientStatus = mStatusBarController.isTransientShowRequested()
John Spurlockf1a36642013-10-12 17:50:42 -04008336 && !transientStatusBarAllowed && hideStatusBarSysui;
Wale Ogunwale6e94a9e2015-10-07 15:35:49 -07008337 final boolean denyTransientNav = mNavigationBarController.isTransientShowRequested()
John Spurlockf1a36642013-10-12 17:50:42 -04008338 && !transientNavBarAllowed;
Jorim Jaggi0ffd49c2016-02-12 15:04:21 -08008339 if (denyTransientStatus || denyTransientNav || mForceShowSystemBars) {
John Spurlock27735a42013-08-14 17:57:38 -04008340 // clear the clearable flags instead
John Spurlockf1a36642013-10-12 17:50:42 -04008341 clearClearableFlagsLw();
tiger_huangc58d7562014-10-23 20:24:19 +08008342 vis &= ~View.SYSTEM_UI_CLEARABLE_FLAGS;
John Spurlockad3e6cb2013-04-30 08:47:43 -04008343 }
John Spurlock27735a42013-08-14 17:57:38 -04008344
Selim Cinekf98702e2015-05-20 22:48:40 -07008345 final boolean immersive = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0;
8346 immersiveSticky = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
8347 final boolean navAllowedHidden = immersive || immersiveSticky;
8348
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08008349 if (hideNavBarSysui && !navAllowedHidden
8350 && getWindowLayerLw(win) > getWindowLayerFromTypeLw(TYPE_INPUT_CONSUMER)) {
Selim Cinekf98702e2015-05-20 22:48:40 -07008351 // We can't hide the navbar from this window otherwise the input consumer would not get
8352 // the input events.
8353 vis = (vis & ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
8354 }
8355
John Spurlock27735a42013-08-14 17:57:38 -04008356 vis = mStatusBarController.updateVisibilityLw(transientStatusBarAllowed, oldVis, vis);
8357
8358 // update navigation bar
John Spurlockf1a36642013-10-12 17:50:42 -04008359 boolean oldImmersiveMode = isImmersiveMode(oldVis);
8360 boolean newImmersiveMode = isImmersiveMode(vis);
8361 if (win != null && oldImmersiveMode != newImmersiveMode) {
John Spurlock79da8332013-09-20 12:04:47 -04008362 final String pkg = win.getOwningPackage();
Amith Yamasani02a03812016-04-22 17:32:00 -07008363 mImmersiveModeConfirmation.immersiveModeChangedLw(pkg, newImmersiveMode,
Adrian Roos7aaa5512016-07-12 15:27:24 -07008364 isUserSetupComplete(), isNavBarEmpty(win.getSystemUiVisibility()));
John Spurlock34e13d92013-08-10 06:52:28 -04008365 }
John Spurlock27735a42013-08-14 17:57:38 -04008366
John Spurlockf1a36642013-10-12 17:50:42 -04008367 vis = mNavigationBarController.updateVisibilityLw(transientNavBarAllowed, oldVis, vis);
8368
Yohei Yukawad0a66b22018-01-10 13:19:54 -08008369 final WindowState navColorWin = chooseNavigationColorWindowLw(
8370 mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState,
8371 mWindowManagerFuncs.getInputMethodWindowLw(), mNavigationBarPosition);
Jorim Jaggi40db0292016-06-27 17:58:03 -07008372 vis = updateLightNavigationBarLw(vis, mTopFullscreenOpaqueWindowState,
Yohei Yukawad0a66b22018-01-10 13:19:54 -08008373 mTopFullscreenOpaqueOrDimmingWindowState,
8374 mWindowManagerFuncs.getInputMethodWindowLw(), navColorWin);
Jorim Jaggi40db0292016-06-27 17:58:03 -07008375
John Spurlocke1f366f2013-08-05 12:22:40 -04008376 return vis;
John Spurlockad3e6cb2013-04-30 08:47:43 -04008377 }
8378
Adrian Roos23df3a32018-03-15 15:41:13 +01008379 private boolean drawsStatusBarBackground(int vis, WindowState win) {
8380 if (!mStatusBarController.isTransparentAllowed(win)) {
8381 return false;
8382 }
8383 if (win == null) {
8384 return true;
8385 }
8386
8387 final boolean drawsSystemBars =
8388 (win.getAttrs().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
8389 final boolean forceDrawsSystemBars =
8390 (win.getAttrs().privateFlags & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0;
8391
8392 return forceDrawsSystemBars || drawsSystemBars && (vis & View.STATUS_BAR_TRANSLUCENT) == 0;
8393 }
8394
Yorke Lee9b2ffb32016-03-07 20:42:01 -08008395 /**
8396 * @return the current visibility flags with the nav-bar opacity related flags toggled based
8397 * on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}.
8398 */
8399 private int configureNavBarOpacity(int visibility, boolean dockedStackVisible,
8400 boolean freeformStackVisible, boolean isDockedDividerResizing) {
Phil Weaverd7551602018-02-15 15:01:04 -08008401 if (mScreenMagnificationActive) {
8402 // When the screen is magnified, the nav bar should be opaque since its background
8403 // can vary as the user pans and zooms
8404 visibility = setNavBarOpaqueFlag(visibility);
8405 } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
Yorke Lee9b2ffb32016-03-07 20:42:01 -08008406 if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) {
8407 visibility = setNavBarOpaqueFlag(visibility);
8408 }
8409 } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) {
8410 if (isDockedDividerResizing) {
8411 visibility = setNavBarOpaqueFlag(visibility);
8412 } else if (freeformStackVisible) {
8413 visibility = setNavBarTranslucentFlag(visibility);
8414 } else {
8415 visibility = setNavBarOpaqueFlag(visibility);
8416 }
8417 }
8418
8419 if (!areTranslucentBarsAllowed()) {
8420 visibility &= ~View.NAVIGATION_BAR_TRANSLUCENT;
8421 }
8422 return visibility;
8423 }
8424
8425 private int setNavBarOpaqueFlag(int visibility) {
8426 return visibility &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT);
8427 }
8428
8429 private int setNavBarTranslucentFlag(int visibility) {
8430 visibility &= ~View.NAVIGATION_BAR_TRANSPARENT;
8431 return visibility |= View.NAVIGATION_BAR_TRANSLUCENT;
8432 }
8433
John Spurlockf1a36642013-10-12 17:50:42 -04008434 private void clearClearableFlagsLw() {
8435 int newVal = mResettingSystemUiFlags | View.SYSTEM_UI_CLEARABLE_FLAGS;
8436 if (newVal != mResettingSystemUiFlags) {
8437 mResettingSystemUiFlags = newVal;
8438 mWindowManagerFuncs.reevaluateStatusBarVisibility();
8439 }
8440 }
8441
8442 private boolean isImmersiveMode(int vis) {
8443 final int flags = View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
John Spurlock34e13d92013-08-10 06:52:28 -04008444 return mNavigationBar != null
8445 && (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0
Daniel Sandler900ece52013-10-18 15:53:27 -04008446 && (vis & flags) != 0
8447 && canHideNavigationBar();
John Spurlock34e13d92013-08-10 06:52:28 -04008448 }
8449
Adrian Roos7aaa5512016-07-12 15:27:24 -07008450 private static boolean isNavBarEmpty(int systemUiFlags) {
8451 final int disableNavigationBar = (View.STATUS_BAR_DISABLE_HOME
8452 | View.STATUS_BAR_DISABLE_BACK
8453 | View.STATUS_BAR_DISABLE_RECENT);
8454
8455 return (systemUiFlags & disableNavigationBar) == disableNavigationBar;
8456 }
8457
Alan Viverette5a0f4ec2013-10-07 15:10:29 -07008458 /**
Daniel Sandlerdd73ee42013-10-11 22:19:59 -04008459 * @return whether the navigation or status bar can be made translucent
8460 *
8461 * This should return true unless touch exploration is not enabled or
8462 * R.boolean.config_enableTranslucentDecor is false.
Alan Viverette5a0f4ec2013-10-07 15:10:29 -07008463 */
Daniel Sandlerdd73ee42013-10-11 22:19:59 -04008464 private boolean areTranslucentBarsAllowed() {
Alan Viverette817f3cd2015-08-13 11:40:14 -04008465 return mTranslucentDecorEnabled;
Alan Viverette5a0f4ec2013-10-07 15:10:29 -07008466 }
8467
Daniel Sandler0c4ccff2011-10-19 16:39:14 -04008468 // Use this instead of checking config_showNavigationBar so that it can be consistently
8469 // overridden by qemu.hw.mainkeys in the emulator.
Craig Mautnereda67292013-04-28 13:50:14 -07008470 @Override
Daniel Sandler0c4ccff2011-10-19 16:39:14 -04008471 public boolean hasNavigationBar() {
8472 return mHasNavigationBar;
8473 }
8474
satok1bc0a492012-04-25 22:47:12 +09008475 @Override
8476 public void setLastInputMethodWindowLw(WindowState ime, WindowState target) {
8477 mLastInputMethodWindow = ime;
8478 mLastInputMethodTargetWindow = target;
8479 }
8480
Craig Mautnerf1b67412012-09-19 13:18:29 -07008481 @Override
Yohei Yukawad6475a62017-04-17 10:35:27 -07008482 public void setDismissImeOnBackKeyPressed(boolean newValue) {
Yohei Yukawaabbe1ac2017-04-18 09:43:05 -07008483 mDismissImeOnBackKeyPressed = newValue;
Yohei Yukawad6475a62017-04-17 10:35:27 -07008484 }
8485
8486 @Override
Craig Mautnerf1b67412012-09-19 13:18:29 -07008487 public void setCurrentUserLw(int newUserId) {
Craig Mautnerd625ab22013-09-06 13:40:31 -07008488 mCurrentUserId = newUserId;
Jim Miller5ecd8112013-01-09 18:50:26 -08008489 if (mKeyguardDelegate != null) {
8490 mKeyguardDelegate.setCurrentUser(newUserId);
Craig Mautnerf1b67412012-09-19 13:18:29 -07008491 }
Phil Weaverce687c52017-03-15 08:51:52 -07008492 if (mAccessibilityShortcutController != null) {
8493 mAccessibilityShortcutController.setCurrentUser(newUserId);
8494 }
Adrian Roosf2efdd82016-04-15 17:43:18 -07008495 StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
Adrian Roos2a629102016-04-15 16:28:03 -07008496 if (statusBar != null) {
Adrian Roosf2efdd82016-04-15 17:43:18 -07008497 statusBar.setCurrentUser(newUserId);
John Spurlock13451a22012-09-28 14:40:41 -04008498 }
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07008499 setLastInputMethodWindowLw(null, null);
Craig Mautnerf1b67412012-09-19 13:18:29 -07008500 }
8501
8502 @Override
Evan Rosky18396452016-07-27 15:19:37 -07008503 public void setSwitchingUser(boolean switching) {
8504 mKeyguardDelegate.setSwitchingUser(switching);
8505 }
8506
8507 @Override
Svetoslav Ganov545252f2012-12-10 18:29:24 -08008508 public boolean isTopLevelWindow(int windowType) {
8509 if (windowType >= WindowManager.LayoutParams.FIRST_SUB_WINDOW
8510 && windowType <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
8511 return (windowType == WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG);
8512 }
8513 return true;
8514 }
8515
Jim Miller4eeb4f62012-11-08 00:04:29 -08008516 @Override
Robert Carr6da3cc02016-06-16 15:17:07 -07008517 public boolean shouldRotateSeamlessly(int oldRotation, int newRotation) {
8518 // For the upside down rotation we don't rotate seamlessly as the navigation
8519 // bar moves position.
8520 // Note most apps (using orientation:sensor or user as opposed to fullSensor)
8521 // will not enter the reverse portrait orientation, so actually the
8522 // orientation won't change at all.
8523 if (oldRotation == mUpsideDownRotation || newRotation == mUpsideDownRotation) {
8524 return false;
8525 }
Robert Carr0b9ac5a2016-10-26 14:12:14 -07008526 // If the navigation bar can't change sides, then it will
8527 // jump when we change orientations and we don't rotate
8528 // seamlessly.
8529 if (!mNavigationBarCanMove) {
8530 return false;
8531 }
Robert Carr6da3cc02016-06-16 15:17:07 -07008532 int delta = newRotation - oldRotation;
8533 if (delta < 0) delta += 4;
8534 // Likewise we don't rotate seamlessly for 180 degree rotations
Geoffrey Pitschb2d6ed32016-08-24 10:37:19 -04008535 // in this case the surfaces never resize, and our logic to
Robert Carr6da3cc02016-06-16 15:17:07 -07008536 // revert the transformations on size change will fail. We could
8537 // fix this in the future with the "tagged" frames idea.
8538 if (delta == Surface.ROTATION_180) {
8539 return false;
8540 }
8541
Robert Carr57d9fbd2016-08-15 12:00:35 -07008542 final WindowState w = mTopFullscreenOpaqueWindowState;
Robert Carr828ec3dc2016-08-22 13:32:34 -07008543 if (w != mFocusedWindow) {
8544 return false;
8545 }
Robert Carr57d9fbd2016-08-15 12:00:35 -07008546
Robert Carr606f4d52016-06-30 14:36:27 -07008547 // We only enable seamless rotation if the top window has requested
8548 // it and is in the fullscreen opaque state. Seamless rotation
8549 // requires freezing various Surface states and won't work well
8550 // with animations, so we disable it in the animation case for now.
Robert Carr1ccd4252016-08-15 12:05:21 -07008551 if (w != null && !w.isAnimatingLw() &&
Robert Carr57d9fbd2016-08-15 12:00:35 -07008552 ((w.getAttrs().rotationAnimation == ROTATION_ANIMATION_JUMPCUT) ||
8553 (w.getAttrs().rotationAnimation == ROTATION_ANIMATION_SEAMLESS))) {
Robert Carr6da3cc02016-06-16 15:17:07 -07008554 return true;
8555 }
8556 return false;
8557 }
8558
8559 @Override
Phil Weaverd7551602018-02-15 15:01:04 -08008560 public void onScreenMagnificationStateChanged(boolean active) {
8561 synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
8562 mScreenMagnificationActive = active;
8563 updateSystemUiVisibilityLw();
8564 }
8565 }
8566
8567 @Override
Steven Timotiusaf03df62017-07-18 16:56:43 -07008568 public void writeToProto(ProtoOutputStream proto, long fieldId) {
8569 final long token = proto.start(fieldId);
Vishnu Nair9a3e4062018-01-11 08:42:54 -08008570 proto.write(LAST_SYSTEM_UI_FLAGS, mLastSystemUiFlags);
8571 proto.write(ROTATION_MODE, mUserRotationMode);
8572 proto.write(ROTATION, mUserRotation);
8573 proto.write(ORIENTATION, mCurrentAppOrientation);
8574 proto.write(SCREEN_ON_FULLY, mScreenOnFully);
8575 proto.write(KEYGUARD_DRAW_COMPLETE, mKeyguardDrawComplete);
8576 proto.write(WINDOW_MANAGER_DRAW_COMPLETE, mWindowManagerDrawComplete);
8577 if (mFocusedApp != null) {
8578 proto.write(FOCUSED_APP_TOKEN, mFocusedApp.toString());
8579 }
8580 if (mFocusedWindow != null) {
8581 mFocusedWindow.writeIdentifierToProto(proto, FOCUSED_WINDOW);
8582 }
8583 if (mTopFullscreenOpaqueWindowState != null) {
8584 mTopFullscreenOpaqueWindowState.writeIdentifierToProto(
8585 proto, TOP_FULLSCREEN_OPAQUE_WINDOW);
8586 }
8587 if (mTopFullscreenOpaqueOrDimmingWindowState != null) {
8588 mTopFullscreenOpaqueOrDimmingWindowState.writeIdentifierToProto(
8589 proto, TOP_FULLSCREEN_OPAQUE_OR_DIMMING_WINDOW);
8590 }
8591 proto.write(KEYGUARD_OCCLUDED, mKeyguardOccluded);
8592 proto.write(KEYGUARD_OCCLUDED_CHANGED, mKeyguardOccludedChanged);
8593 proto.write(KEYGUARD_OCCLUDED_PENDING, mPendingKeyguardOccluded);
8594 proto.write(FORCE_STATUS_BAR, mForceStatusBar);
8595 proto.write(FORCE_STATUS_BAR_FROM_KEYGUARD, mForceStatusBarFromKeyguard);
8596 mStatusBarController.writeToProto(proto, STATUS_BAR);
8597 mNavigationBarController.writeToProto(proto, NAVIGATION_BAR);
8598 if (mOrientationListener != null) {
8599 mOrientationListener.writeToProto(proto, ORIENTATION_LISTENER);
8600 }
8601 if (mKeyguardDelegate != null) {
8602 mKeyguardDelegate.writeToProto(proto, KEYGUARD_DELEGATE);
8603 }
Steven Timotiusaf03df62017-07-18 16:56:43 -07008604 proto.end(token);
8605 }
8606
8607 @Override
Jeff Brownd7a04de2012-06-17 14:17:52 -07008608 public void dump(String prefix, PrintWriter pw, String[] args) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008609 pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode);
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07008610 pw.print(" mSystemReady="); pw.print(mSystemReady);
8611 pw.print(" mSystemBooted="); pw.println(mSystemBooted);
Michael Wright19859762017-09-18 20:57:58 +01008612 pw.print(prefix); pw.print("mLidState=");
8613 pw.print(WindowManagerFuncs.lidStateToString(mLidState));
8614 pw.print(" mLidOpenRotation=");
8615 pw.println(Surface.rotationToString(mLidOpenRotation));
8616 pw.print(prefix); pw.print("mCameraLensCoverState=");
8617 pw.print(WindowManagerFuncs.cameraLensStateToString(mCameraLensCoverState));
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008618 pw.print(" mHdmiPlugged="); pw.println(mHdmiPlugged);
Dianne Hackborne26ab702011-10-16 13:21:33 -07008619 if (mLastSystemUiFlags != 0 || mResettingSystemUiFlags != 0
8620 || mForceClearedSystemUiFlags != 0) {
8621 pw.print(prefix); pw.print("mLastSystemUiFlags=0x");
8622 pw.print(Integer.toHexString(mLastSystemUiFlags));
8623 pw.print(" mResettingSystemUiFlags=0x");
8624 pw.print(Integer.toHexString(mResettingSystemUiFlags));
8625 pw.print(" mForceClearedSystemUiFlags=0x");
8626 pw.println(Integer.toHexString(mForceClearedSystemUiFlags));
Dianne Hackborndf89e652011-10-06 22:35:11 -07008627 }
Dianne Hackborn4eff8d32011-11-10 19:38:40 -08008628 if (mLastFocusNeedsMenu) {
8629 pw.print(prefix); pw.print("mLastFocusNeedsMenu=");
8630 pw.println(mLastFocusNeedsMenu);
8631 }
Jeff Browna20dda42014-05-27 20:57:24 -07008632 pw.print(prefix); pw.print("mWakeGestureEnabledSetting=");
8633 pw.println(mWakeGestureEnabledSetting);
8634
Michael Wright19859762017-09-18 20:57:58 +01008635 pw.print(prefix);
8636 pw.print("mSupportAutoRotation="); pw.print(mSupportAutoRotation);
8637 pw.print(" mOrientationSensorEnabled="); pw.println(mOrientationSensorEnabled);
8638 pw.print(prefix); pw.print("mUiMode="); pw.print(Configuration.uiModeToString(mUiMode));
8639 pw.print(" mDockMode="); pw.println(Intent.dockStateToString(mDockMode));
8640 pw.print(prefix); pw.print("mEnableCarDockHomeCapture=");
8641 pw.print(mEnableCarDockHomeCapture);
8642 pw.print(" mCarDockRotation=");
8643 pw.print(Surface.rotationToString(mCarDockRotation));
8644 pw.print(" mDeskDockRotation=");
8645 pw.println(Surface.rotationToString(mDeskDockRotation));
8646 pw.print(prefix); pw.print("mUserRotationMode=");
8647 pw.print(WindowManagerPolicy.userRotationModeToString(mUserRotationMode));
8648 pw.print(" mUserRotation="); pw.print(Surface.rotationToString(mUserRotation));
8649 pw.print(" mAllowAllRotations=");
8650 pw.println(allowAllRotationsToString(mAllowAllRotations));
8651 pw.print(prefix); pw.print("mCurrentAppOrientation=");
8652 pw.println(ActivityInfo.screenOrientationToString(mCurrentAppOrientation));
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008653 pw.print(prefix); pw.print("mCarDockEnablesAccelerometer=");
8654 pw.print(mCarDockEnablesAccelerometer);
8655 pw.print(" mDeskDockEnablesAccelerometer=");
8656 pw.println(mDeskDockEnablesAccelerometer);
8657 pw.print(prefix); pw.print("mLidKeyboardAccessibility=");
8658 pw.print(mLidKeyboardAccessibility);
8659 pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility);
Edward Savage-Jones7def60d2015-11-13 13:27:03 +01008660 pw.print(" mLidControlsScreenLock="); pw.println(mLidControlsScreenLock);
Michael Wright19859762017-09-18 20:57:58 +01008661 pw.print(prefix); pw.print("mLidControlsSleep="); pw.println(mLidControlsSleep);
Jeff Brown6d8fd272014-05-20 21:24:38 -07008662 pw.print(prefix);
Michael Wright19859762017-09-18 20:57:58 +01008663 pw.print("mLongPressOnBackBehavior=");
8664 pw.println(longPressOnBackBehaviorToString(mLongPressOnBackBehavior));
Anthony Hugh34f09ca2016-03-04 12:03:37 -08008665 pw.print(prefix);
Michael Wright19859762017-09-18 20:57:58 +01008666 pw.print("mLongPressOnHomeBehavior=");
8667 pw.println(longPressOnHomeBehaviorToString(mLongPressOnHomeBehavior));
8668 pw.print(prefix);
8669 pw.print("mDoubleTapOnHomeBehavior=");
8670 pw.println(doubleTapOnHomeBehaviorToString(mDoubleTapOnHomeBehavior));
8671 pw.print(prefix);
8672 pw.print("mShortPressOnPowerBehavior=");
8673 pw.println(shortPressOnPowerBehaviorToString(mShortPressOnPowerBehavior));
8674 pw.print(prefix);
8675 pw.print("mLongPressOnPowerBehavior=");
8676 pw.println(longPressOnPowerBehaviorToString(mLongPressOnPowerBehavior));
8677 pw.print(prefix);
Michael Kwan57908f02017-11-14 15:27:53 -08008678 pw.print("mVeryLongPressOnPowerBehavior=");
8679 pw.println(veryLongPressOnPowerBehaviorToString(mVeryLongPressOnPowerBehavior));
8680 pw.print(prefix);
Michael Wright19859762017-09-18 20:57:58 +01008681 pw.print("mDoublePressOnPowerBehavior=");
8682 pw.println(multiPressOnPowerBehaviorToString(mDoublePressOnPowerBehavior));
8683 pw.print(prefix);
8684 pw.print("mTriplePressOnPowerBehavior=");
8685 pw.println(multiPressOnPowerBehaviorToString(mTriplePressOnPowerBehavior));
8686 pw.print(prefix);
8687 pw.print("mShortPressOnSleepBehavior=");
8688 pw.println(shortPressOnSleepBehaviorToString(mShortPressOnSleepBehavior));
8689 pw.print(prefix);
8690 pw.print("mShortPressOnWindowBehavior=");
8691 pw.println(shortPressOnWindowBehaviorToString(mShortPressOnWindowBehavior));
8692 pw.print(prefix);
Michael Kwan7f171692018-04-04 14:00:53 -07008693 pw.print("mAllowStartActivityForLongPressOnPowerDuringSetup=");
8694 pw.println(mAllowStartActivityForLongPressOnPowerDuringSetup);
8695 pw.print(prefix);
Michael Wright19859762017-09-18 20:57:58 +01008696 pw.print("mHasSoftInput="); pw.print(mHasSoftInput);
8697 pw.print(" mDismissImeOnBackKeyPressed="); pw.println(mDismissImeOnBackKeyPressed);
8698 pw.print(prefix);
8699 pw.print("mIncallPowerBehavior=");
8700 pw.print(incallPowerBehaviorToString(mIncallPowerBehavior));
8701 pw.print(" mIncallBackBehavior=");
8702 pw.print(incallBackBehaviorToString(mIncallBackBehavior));
8703 pw.print(" mEndcallBehavior=");
8704 pw.println(endcallBehaviorToString(mEndcallBehavior));
8705 pw.print(prefix); pw.print("mHomePressed="); pw.println(mHomePressed);
8706 pw.print(prefix);
8707 pw.print("mAwake="); pw.print(mAwake);
8708 pw.print("mScreenOnEarly="); pw.print(mScreenOnEarly);
Jeff Brown3ee549c2014-09-22 20:14:39 -07008709 pw.print(" mScreenOnFully="); pw.println(mScreenOnFully);
8710 pw.print(prefix); pw.print("mKeyguardDrawComplete="); pw.print(mKeyguardDrawComplete);
8711 pw.print(" mWindowManagerDrawComplete="); pw.println(mWindowManagerDrawComplete);
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008712 pw.print(prefix); pw.print("mDockLayer="); pw.print(mDockLayer);
8713 pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer);
Jorim Jaggi8d786932016-10-26 19:08:36 -07008714 pw.print(prefix); pw.print("mShowingDream="); pw.print(mShowingDream);
Jeff Brown061ea992015-04-17 19:55:47 -07008715 pw.print(" mDreamingLockscreen="); pw.print(mDreamingLockscreen);
8716 pw.print(" mDreamingSleepToken="); pw.println(mDreamingSleepToken);
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07008717 if (mLastInputMethodWindow != null) {
8718 pw.print(prefix); pw.print("mLastInputMethodWindow=");
8719 pw.println(mLastInputMethodWindow);
8720 }
8721 if (mLastInputMethodTargetWindow != null) {
8722 pw.print(prefix); pw.print("mLastInputMethodTargetWindow=");
8723 pw.println(mLastInputMethodTargetWindow);
8724 }
8725 if (mStatusBar != null) {
8726 pw.print(prefix); pw.print("mStatusBar=");
Dianne Hackbornae6688b2015-02-11 17:02:41 -08008727 pw.print(mStatusBar); pw.print(" isStatusBarKeyguard=");
8728 pw.println(isStatusBarKeyguard());
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07008729 }
8730 if (mNavigationBar != null) {
8731 pw.print(prefix); pw.print("mNavigationBar=");
8732 pw.println(mNavigationBar);
8733 }
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07008734 if (mFocusedWindow != null) {
8735 pw.print(prefix); pw.print("mFocusedWindow=");
8736 pw.println(mFocusedWindow);
8737 }
8738 if (mFocusedApp != null) {
8739 pw.print(prefix); pw.print("mFocusedApp=");
8740 pw.println(mFocusedApp);
8741 }
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07008742 if (mTopFullscreenOpaqueWindowState != null) {
8743 pw.print(prefix); pw.print("mTopFullscreenOpaqueWindowState=");
8744 pw.println(mTopFullscreenOpaqueWindowState);
8745 }
Adrian Rooscd3884d2015-02-18 17:25:23 +01008746 if (mTopFullscreenOpaqueOrDimmingWindowState != null) {
8747 pw.print(prefix); pw.print("mTopFullscreenOpaqueOrDimmingWindowState=");
8748 pw.println(mTopFullscreenOpaqueOrDimmingWindowState);
8749 }
Dianne Hackborn891d3fb2013-01-09 18:31:37 -08008750 if (mForcingShowNavBar) {
8751 pw.print(prefix); pw.print("mForcingShowNavBar=");
8752 pw.println(mForcingShowNavBar); pw.print( "mForcingShowNavBarLayer=");
8753 pw.println(mForcingShowNavBarLayer);
8754 }
Dianne Hackborn7ad44382012-10-18 17:46:00 -07008755 pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen);
Jorim Jaggife762342016-10-13 14:33:27 +02008756 pw.print(" mKeyguardOccluded="); pw.println(mKeyguardOccluded);
Michael Wright19859762017-09-18 20:57:58 +01008757 pw.print(prefix);
8758 pw.print("mKeyguardOccludedChanged="); pw.print(mKeyguardOccludedChanged);
Jorim Jaggi8d786932016-10-26 19:08:36 -07008759 pw.print(" mPendingKeyguardOccluded="); pw.println(mPendingKeyguardOccluded);
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008760 pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar);
8761 pw.print(" mForceStatusBarFromKeyguard=");
8762 pw.println(mForceStatusBarFromKeyguard);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008763 pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn);
8764 pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout);
8765 pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive);
Michael Wright19859762017-09-18 20:57:58 +01008766 pw.print(prefix); pw.print("mLandscapeRotation=");
8767 pw.print(Surface.rotationToString(mLandscapeRotation));
8768 pw.print(" mSeascapeRotation=");
8769 pw.println(Surface.rotationToString(mSeascapeRotation));
8770 pw.print(prefix); pw.print("mPortraitRotation=");
8771 pw.print(Surface.rotationToString(mPortraitRotation));
8772 pw.print(" mUpsideDownRotation=");
8773 pw.println(Surface.rotationToString(mUpsideDownRotation));
8774 pw.print(prefix); pw.print("mDemoHdmiRotation=");
8775 pw.print(Surface.rotationToString(mDemoHdmiRotation));
Jeff Brownc82c89ed2013-04-17 17:18:15 -07008776 pw.print(" mDemoHdmiRotationLock="); pw.println(mDemoHdmiRotationLock);
Michael Wright19859762017-09-18 20:57:58 +01008777 pw.print(prefix); pw.print("mUndockedHdmiRotation=");
8778 pw.println(Surface.rotationToString(mUndockedHdmiRotation));
Sujith Ramakrishnan6bed9bd2017-04-26 12:33:37 -07008779 if (mHasFeatureLeanback) {
8780 pw.print(prefix);
8781 pw.print("mAccessibilityTvKey1Pressed="); pw.println(mAccessibilityTvKey1Pressed);
8782 pw.print(prefix);
8783 pw.print("mAccessibilityTvKey2Pressed="); pw.println(mAccessibilityTvKey2Pressed);
8784 pw.print(prefix);
8785 pw.print("mAccessibilityTvScheduled="); pw.println(mAccessibilityTvScheduled);
8786 }
Jeff Brown600f0032014-05-22 17:06:00 -07008787
Tim Kilbournd7c0c2e2014-05-29 16:08:10 -07008788 mGlobalKeyManager.dump(prefix, pw);
John Spurlock27735a42013-08-14 17:57:38 -04008789 mStatusBarController.dump(pw, prefix);
8790 mNavigationBarController.dump(pw, prefix);
John Spurlockc6d1c602014-01-17 15:22:06 -05008791 PolicyControl.dump(prefix, pw);
Jeff Brown600f0032014-05-22 17:06:00 -07008792
Jeff Browna20dda42014-05-27 20:57:24 -07008793 if (mWakeGestureListener != null) {
8794 mWakeGestureListener.dump(pw, prefix);
8795 }
Jeff Brown600f0032014-05-22 17:06:00 -07008796 if (mOrientationListener != null) {
8797 mOrientationListener.dump(pw, prefix);
8798 }
Filip Gruszczynskicfb31852015-02-25 21:47:12 +00008799 if (mBurnInProtectionHelper != null) {
8800 mBurnInProtectionHelper.dump(prefix, pw);
8801 }
Jorim Jaggi84dc08a2015-09-11 17:45:22 -07008802 if (mKeyguardDelegate != null) {
8803 mKeyguardDelegate.dump(prefix, pw);
8804 }
Michael Wright19859762017-09-18 20:57:58 +01008805
8806 pw.print(prefix); pw.println("Looper state:");
8807 mHandler.getLooper().dump(new PrintWriterPrinter(pw), prefix + " ");
8808 }
8809
8810 private static String allowAllRotationsToString(int allowAll) {
8811 switch (allowAll) {
8812 case -1:
8813 return "unknown";
8814 case 0:
8815 return "false";
8816 case 1:
8817 return "true";
8818 default:
8819 return Integer.toString(allowAll);
8820 }
8821 }
8822
8823 private static String endcallBehaviorToString(int behavior) {
8824 StringBuilder sb = new StringBuilder();
8825 if ((behavior & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0 ) {
8826 sb.append("home|");
8827 }
8828 if ((behavior & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
8829 sb.append("sleep|");
8830 }
8831
8832 final int N = sb.length();
8833 if (N == 0) {
8834 return "<nothing>";
8835 } else {
8836 // Chop off the trailing '|'
8837 return sb.substring(0, N - 1);
8838 }
8839 }
8840
8841 private static String incallPowerBehaviorToString(int behavior) {
8842 if ((behavior & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0) {
8843 return "hangup";
8844 } else {
8845 return "sleep";
8846 }
8847 }
8848
8849 private static String incallBackBehaviorToString(int behavior) {
8850 if ((behavior & Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR_HANGUP) != 0) {
8851 return "hangup";
8852 } else {
8853 return "<nothing>";
8854 }
8855 }
8856
8857 private static String longPressOnBackBehaviorToString(int behavior) {
8858 switch (behavior) {
8859 case LONG_PRESS_BACK_NOTHING:
8860 return "LONG_PRESS_BACK_NOTHING";
8861 case LONG_PRESS_BACK_GO_TO_VOICE_ASSIST:
8862 return "LONG_PRESS_BACK_GO_TO_VOICE_ASSIST";
8863 default:
8864 return Integer.toString(behavior);
8865 }
8866 }
8867
Michael Wright19859762017-09-18 20:57:58 +01008868 private static String longPressOnHomeBehaviorToString(int behavior) {
8869 switch (behavior) {
8870 case LONG_PRESS_HOME_NOTHING:
8871 return "LONG_PRESS_HOME_NOTHING";
8872 case LONG_PRESS_HOME_ALL_APPS:
8873 return "LONG_PRESS_HOME_ALL_APPS";
8874 case LONG_PRESS_HOME_ASSIST:
8875 return "LONG_PRESS_HOME_ASSIST";
8876 default:
8877 return Integer.toString(behavior);
8878 }
8879 }
8880
8881 private static String doubleTapOnHomeBehaviorToString(int behavior) {
8882 switch (behavior) {
8883 case DOUBLE_TAP_HOME_NOTHING:
8884 return "DOUBLE_TAP_HOME_NOTHING";
8885 case DOUBLE_TAP_HOME_RECENT_SYSTEM_UI:
8886 return "DOUBLE_TAP_HOME_RECENT_SYSTEM_UI";
8887 default:
8888 return Integer.toString(behavior);
8889 }
8890 }
8891
8892 private static String shortPressOnPowerBehaviorToString(int behavior) {
8893 switch (behavior) {
8894 case SHORT_PRESS_POWER_NOTHING:
8895 return "SHORT_PRESS_POWER_NOTHING";
8896 case SHORT_PRESS_POWER_GO_TO_SLEEP:
8897 return "SHORT_PRESS_POWER_GO_TO_SLEEP";
8898 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
8899 return "SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP";
8900 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
8901 return "SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME";
8902 case SHORT_PRESS_POWER_GO_HOME:
8903 return "SHORT_PRESS_POWER_GO_HOME";
8904 case SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME:
8905 return "SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME";
8906 default:
8907 return Integer.toString(behavior);
8908 }
8909 }
8910
8911 private static String longPressOnPowerBehaviorToString(int behavior) {
8912 switch (behavior) {
8913 case LONG_PRESS_POWER_NOTHING:
8914 return "LONG_PRESS_POWER_NOTHING";
8915 case LONG_PRESS_POWER_GLOBAL_ACTIONS:
8916 return "LONG_PRESS_POWER_GLOBAL_ACTIONS";
8917 case LONG_PRESS_POWER_SHUT_OFF:
8918 return "LONG_PRESS_POWER_SHUT_OFF";
8919 case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
8920 return "LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM";
8921 default:
8922 return Integer.toString(behavior);
8923 }
8924 }
Michael Kwan57908f02017-11-14 15:27:53 -08008925
8926 private static String veryLongPressOnPowerBehaviorToString(int behavior) {
8927 switch (behavior) {
8928 case VERY_LONG_PRESS_POWER_NOTHING:
8929 return "VERY_LONG_PRESS_POWER_NOTHING";
8930 case VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS:
8931 return "VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS";
8932 default:
8933 return Integer.toString(behavior);
8934 }
8935 }
8936
Michael Wright19859762017-09-18 20:57:58 +01008937 private static String multiPressOnPowerBehaviorToString(int behavior) {
8938 switch (behavior) {
8939 case MULTI_PRESS_POWER_NOTHING:
8940 return "MULTI_PRESS_POWER_NOTHING";
8941 case MULTI_PRESS_POWER_THEATER_MODE:
8942 return "MULTI_PRESS_POWER_THEATER_MODE";
8943 case MULTI_PRESS_POWER_BRIGHTNESS_BOOST:
8944 return "MULTI_PRESS_POWER_BRIGHTNESS_BOOST";
8945 default:
8946 return Integer.toString(behavior);
8947 }
8948 }
8949
8950 private static String shortPressOnSleepBehaviorToString(int behavior) {
8951 switch (behavior) {
8952 case SHORT_PRESS_SLEEP_GO_TO_SLEEP:
8953 return "SHORT_PRESS_SLEEP_GO_TO_SLEEP";
8954 case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME:
8955 return "SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME";
8956 default:
8957 return Integer.toString(behavior);
8958 }
8959 }
8960
8961 private static String shortPressOnWindowBehaviorToString(int behavior) {
8962 switch (behavior) {
8963 case SHORT_PRESS_WINDOW_NOTHING:
8964 return "SHORT_PRESS_WINDOW_NOTHING";
8965 case SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE:
8966 return "SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE";
8967 default:
8968 return Integer.toString(behavior);
8969 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008970 }
Benjamin Franz3662b152018-01-16 17:23:44 +00008971
8972 @Override
8973 public void onLockTaskStateChangedLw(int lockTaskState) {
8974 mImmersiveModeConfirmation.onLockTaskModeChangedLw(lockTaskState);
8975 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08008976}