blob: 2b5eb3ac29fb560ff321085f2cd444a2c4060118 [file] [log] [blame]
Jorim Jaggife762342016-10-13 14:33:27 +02001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Jorim Jaggife762342016-10-13 14:33:27 +020018
Wale Ogunwaledfb7fb22017-06-23 14:52:40 -070019import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
David Stevens9440dc82017-03-16 19:00:20 -070020import static android.view.Display.DEFAULT_DISPLAY;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070021import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
Issei Suzuki5609ccb2019-06-13 15:04:08 +020022import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070023import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
24import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
25import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
26import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
27import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
28import static android.view.WindowManager.TRANSIT_UNSET;
Adrian Roose99bc052017-11-20 17:55:31 +010029import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
Issei Suzuki5609ccb2019-06-13 15:04:08 +020030import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS;
Adrian Roose99bc052017-11-20 17:55:31 +010031import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
32import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
wilsonshih0299c8a2018-08-24 15:52:57 +080033
Issei Suzukid6eb5a22019-02-20 23:08:03 +010034import static com.android.server.am.KeyguardControllerProto.AOD_SHOWING;
wilsonshih0299c8a2018-08-24 15:52:57 +080035import static com.android.server.am.KeyguardControllerProto.KEYGUARD_OCCLUDED_STATES;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070036import static com.android.server.am.KeyguardControllerProto.KEYGUARD_SHOWING;
wilsonshih0299c8a2018-08-24 15:52:57 +080037import static com.android.server.am.KeyguardOccludedProto.DISPLAY_ID;
38import static com.android.server.am.KeyguardOccludedProto.KEYGUARD_OCCLUDED;
wilsonshihe7903ea2018-09-26 16:17:59 +080039import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
40import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
41import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Jorim Jaggife762342016-10-13 14:33:27 +020042
Jorim Jaggi241ae102016-11-02 21:57:33 -070043import android.os.IBinder;
44import android.os.RemoteException;
Wale Ogunwaledfb7fb22017-06-23 14:52:40 -070045import android.os.Trace;
wilsonshih30eca702019-07-10 09:22:11 +080046import android.util.EventLog;
Jorim Jaggi241ae102016-11-02 21:57:33 -070047import android.util.Slog;
wilsonshih0299c8a2018-08-24 15:52:57 +080048import android.util.SparseArray;
Steven Timotius4346f0a2017-09-12 11:07:21 -070049import android.util.proto.ProtoOutputStream;
Adrian Roose99bc052017-11-20 17:55:31 +010050
Jorim Jaggi241ae102016-11-02 21:57:33 -070051import com.android.internal.policy.IKeyguardDismissCallback;
wilsonshih30eca702019-07-10 09:22:11 +080052import com.android.server.am.EventLogTags;
Adrian Roose99bc052017-11-20 17:55:31 +010053import com.android.server.policy.WindowManagerPolicy;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070054import com.android.server.wm.ActivityTaskManagerInternal.SleepToken;
Adrian Roose99bc052017-11-20 17:55:31 +010055
Jorim Jaggi8d786932016-10-26 19:08:36 -070056import java.io.PrintWriter;
Jorim Jaggife762342016-10-13 14:33:27 +020057
58/**
59 * Controls Keyguard occluding, dismissing and transitions depending on what kind of activities are
60 * currently visible.
61 * <p>
62 * Note that everything in this class should only be accessed with the AM lock being held.
63 */
64class KeyguardController {
65
Wale Ogunwale98875612018-10-12 07:53:02 -070066 private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardController" : TAG_ATM;
Jorim Jaggi241ae102016-11-02 21:57:33 -070067
Jorim Jaggife762342016-10-13 14:33:27 +020068 private final ActivityStackSupervisor mStackSupervisor;
69 private WindowManagerService mWindowManager;
Jorim Jaggife762342016-10-13 14:33:27 +020070 private boolean mKeyguardShowing;
Lucas Dupin47a65c72018-02-15 14:16:18 -080071 private boolean mAodShowing;
Jorim Jaggi8d786932016-10-26 19:08:36 -070072 private boolean mKeyguardGoingAway;
Jorim Jaggi07961872016-11-23 11:28:57 +010073 private boolean mDismissalRequested;
Jorim Jaggife762342016-10-13 14:33:27 +020074 private int mBeforeUnoccludeTransit;
75 private int mVisibilityTransactionDepth;
wilsonshih0299c8a2018-08-24 15:52:57 +080076 private final SparseArray<KeyguardDisplayState> mDisplayStates = new SparseArray<>();
77 private final ActivityTaskManagerService mService;
Wale Ogunwaled32da472018-11-16 07:19:28 -080078 private RootActivityContainer mRootActivityContainer;
Jorim Jaggife762342016-10-13 14:33:27 +020079
Wale Ogunwalef6733932018-06-27 05:14:34 -070080 KeyguardController(ActivityTaskManagerService service,
Jorim Jaggife762342016-10-13 14:33:27 +020081 ActivityStackSupervisor stackSupervisor) {
82 mService = service;
83 mStackSupervisor = stackSupervisor;
84 }
85
86 void setWindowManager(WindowManagerService windowManager) {
87 mWindowManager = windowManager;
Wale Ogunwaled32da472018-11-16 07:19:28 -080088 mRootActivityContainer = mService.mRootActivityContainer;
Jorim Jaggife762342016-10-13 14:33:27 +020089 }
90
91 /**
Issei Suzuki16d4de52019-07-29 13:12:01 +000092 * @return true if either Keyguard or AOD are showing, not going away, and not being occluded
93 * on the given display, false otherwise.
Lucas Dupin47a65c72018-02-15 14:16:18 -080094 */
95 boolean isKeyguardOrAodShowing(int displayId) {
Issei Suzuki16d4de52019-07-29 13:12:01 +000096 return (mKeyguardShowing || mAodShowing) && !mKeyguardGoingAway
97 && !isDisplayOccluded(displayId);
98 }
99
100 /**
101 * @return {@code true} for default display when AOD is showing. Otherwise, same as
102 * {@link #isKeyguardOrAodShowing(int)}
103 * TODO(b/125198167): Replace isKeyguardOrAodShowing() by this logic.
104 */
105 boolean isKeyguardUnoccludedOrAodShowing(int displayId) {
106 if (displayId == DEFAULT_DISPLAY && mAodShowing) {
107 return true;
108 }
109 return isKeyguardOrAodShowing(displayId);
Issei Suzukid6eb5a22019-02-20 23:08:03 +0100110 }
111
112 /**
David Stevens53a39ea2017-08-23 18:41:49 -0700113 * @return true if Keyguard is showing, not going away, and not being occluded on the given
114 * display, false otherwise
Jorim Jaggife762342016-10-13 14:33:27 +0200115 */
David Stevens53a39ea2017-08-23 18:41:49 -0700116 boolean isKeyguardShowing(int displayId) {
Issei Suzuki16d4de52019-07-29 13:12:01 +0000117 return mKeyguardShowing && !mKeyguardGoingAway && !isDisplayOccluded(displayId);
Jorim Jaggife762342016-10-13 14:33:27 +0200118 }
119
120 /**
121 * @return true if Keyguard is either showing or occluded, but not going away
122 */
123 boolean isKeyguardLocked() {
124 return mKeyguardShowing && !mKeyguardGoingAway;
125 }
126
127 /**
Bryce Lee271617a2018-03-15 10:39:12 -0700128 * @return {@code true} if the keyguard is going away, {@code false} otherwise.
129 */
130 boolean isKeyguardGoingAway() {
131 // Also check keyguard showing in case value is stale.
132 return mKeyguardGoingAway && mKeyguardShowing;
133 }
134
135 /**
Jorim Jaggife762342016-10-13 14:33:27 +0200136 * Update the Keyguard showing state.
137 */
wilsonshih177261f2019-02-22 12:02:18 +0800138 void setKeyguardShown(boolean keyguardShowing, boolean aodShowing) {
Adrian Roos6ec76b72018-04-25 14:01:11 +0200139 // If keyguard is going away, but SystemUI aborted the transition, need to reset state.
wilsonshih2bc846c2019-05-02 14:35:21 +0800140 final boolean keyguardChanged = keyguardShowing != mKeyguardShowing
141 || mKeyguardGoingAway && keyguardShowing;
142 final boolean aodChanged = aodShowing != mAodShowing;
143 if (!keyguardChanged && !aodChanged) {
Jorim Jaggife762342016-10-13 14:33:27 +0200144 return;
145 }
wilsonshih30eca702019-07-10 09:22:11 +0800146 EventLog.writeEvent(EventLogTags.AM_SET_KEYGUARD_SHOWN,
147 keyguardShowing ? 1 : 0,
148 aodShowing ? 1 : 0,
149 mKeyguardGoingAway ? 1 : 0,
150 "setKeyguardShown");
Lucas Dupin47a65c72018-02-15 14:16:18 -0800151 mKeyguardShowing = keyguardShowing;
152 mAodShowing = aodShowing;
chaviw0e9fb132018-06-05 16:29:13 -0700153 mWindowManager.setAodShowing(aodShowing);
wilsonshih2bc846c2019-05-02 14:35:21 +0800154
155 if (keyguardChanged) {
156 // Irrelevant to AOD.
David Stevens53a39ea2017-08-23 18:41:49 -0700157 dismissDockedStackIfNeeded();
Andrii Kulian0d595f32018-02-21 15:47:33 -0800158 setKeyguardGoingAway(false);
Lucas Dupin47a65c72018-02-15 14:16:18 -0800159 if (keyguardShowing) {
David Stevens53a39ea2017-08-23 18:41:49 -0700160 mDismissalRequested = false;
161 }
Jorim Jaggife762342016-10-13 14:33:27 +0200162 }
wilsonshih2bc846c2019-05-02 14:35:21 +0800163 // TODO(b/113840485): Check usage for non-default display
164 mWindowManager.setKeyguardOrAodShowingOnDefaultDisplay(
165 isKeyguardOrAodShowing(DEFAULT_DISPLAY));
166
167 // Update the sleep token first such that ensureActivitiesVisible has correct sleep token
168 // state when evaluating visibilities.
David Stevens9440dc82017-03-16 19:00:20 -0700169 updateKeyguardSleepToken();
wilsonshih2bc846c2019-05-02 14:35:21 +0800170 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
Jorim Jaggife762342016-10-13 14:33:27 +0200171 }
172
173 /**
174 * Called when Keyguard is going away.
175 *
Adrian Roose99bc052017-11-20 17:55:31 +0100176 * @param flags See {@link WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
Jorim Jaggife762342016-10-13 14:33:27 +0200177 * etc.
178 */
179 void keyguardGoingAway(int flags) {
Wale Ogunwaledfb7fb22017-06-23 14:52:40 -0700180 if (!mKeyguardShowing) {
181 return;
182 }
183 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway");
Riddle Hsua0022cd2019-09-09 21:12:41 +0800184 mService.deferWindowLayout();
Wale Ogunwaledfb7fb22017-06-23 14:52:40 -0700185 try {
186 setKeyguardGoingAway(true);
wilsonshih30eca702019-07-10 09:22:11 +0800187 EventLog.writeEvent(EventLogTags.AM_SET_KEYGUARD_SHOWN,
188 1 /* keyguardShowing */,
189 mAodShowing ? 1 : 0,
190 1 /* keyguardGoingAway */,
191 "keyguardGoingAway");
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800192 mRootActivityContainer.getDefaultDisplay().mDisplayContent
lumark588a3e82018-07-20 18:53:54 +0800193 .prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
194 false /* alwaysKeepCurrent */, convertTransitFlags(flags),
195 false /* forceOverride */);
David Stevens9440dc82017-03-16 19:00:20 -0700196 updateKeyguardSleepToken();
Jorim Jaggife762342016-10-13 14:33:27 +0200197
Wale Ogunwaledfb7fb22017-06-23 14:52:40 -0700198 // Some stack visibility might change (e.g. docked stack)
Wale Ogunwaled32da472018-11-16 07:19:28 -0800199 mRootActivityContainer.resumeFocusedStacksTopActivities();
200 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
201 mRootActivityContainer.addStartingWindowsForVisibleActivities(
202 true /* taskSwitch */);
Wale Ogunwaledfb7fb22017-06-23 14:52:40 -0700203 mWindowManager.executeAppTransition();
204 } finally {
205 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway: surfaceLayout");
Riddle Hsua0022cd2019-09-09 21:12:41 +0800206 mService.continueWindowLayout();
Wale Ogunwaledfb7fb22017-06-23 14:52:40 -0700207 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
208
209 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
Jorim Jaggife762342016-10-13 14:33:27 +0200210 }
211 }
212
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800213 void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, CharSequence message) {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700214 final ActivityRecord activityRecord = ActivityRecord.forTokenLocked(token);
215 if (activityRecord == null || !activityRecord.visibleIgnoringKeyguard) {
216 failCallback(callback);
217 return;
218 }
Jorim Jaggid7214892017-07-18 14:05:19 +0200219 Slog.i(TAG, "Activity requesting to dismiss Keyguard: " + activityRecord);
chaviw59b98852017-06-13 12:05:44 -0700220
221 // If the client has requested to dismiss the keyguard and the Activity has the flag to
222 // turn the screen on, wakeup the screen if it's the top Activity.
223 if (activityRecord.getTurnScreenOnFlag() && activityRecord.isTopRunningActivity()) {
224 mStackSupervisor.wakeUp("dismissKeyguard");
225 }
226
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800227 mWindowManager.dismissKeyguard(callback, message);
Jorim Jaggi241ae102016-11-02 21:57:33 -0700228 }
229
Wale Ogunwalebfa81ad2017-05-24 15:14:42 -0700230 private void setKeyguardGoingAway(boolean keyguardGoingAway) {
231 mKeyguardGoingAway = keyguardGoingAway;
232 mWindowManager.setKeyguardGoingAway(keyguardGoingAway);
233 }
234
Jorim Jaggi241ae102016-11-02 21:57:33 -0700235 private void failCallback(IKeyguardDismissCallback callback) {
236 try {
237 callback.onDismissError();
238 } catch (RemoteException e) {
239 Slog.w(TAG, "Failed to call callback", e);
240 }
241 }
242
Jorim Jaggife762342016-10-13 14:33:27 +0200243 private int convertTransitFlags(int keyguardGoingAwayFlags) {
244 int result = 0;
245 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0) {
246 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
247 }
248 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0) {
249 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
250 }
251 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0) {
252 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
253 }
Issei Suzuki5609ccb2019-06-13 15:04:08 +0200254 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS) != 0) {
255 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
256 }
Jorim Jaggife762342016-10-13 14:33:27 +0200257 return result;
258 }
259
260 /**
261 * Starts a batch of visibility updates.
262 */
263 void beginActivityVisibilityUpdate() {
264 mVisibilityTransactionDepth++;
265 }
266
267 /**
268 * Ends a batch of visibility updates. After all batches are done, this method makes sure to
269 * update lockscreen occluded/dismiss state if needed.
270 */
271 void endActivityVisibilityUpdate() {
272 mVisibilityTransactionDepth--;
273 if (mVisibilityTransactionDepth == 0) {
274 visibilitiesUpdated();
275 }
276 }
277
Jorim Jaggie69c9312016-10-31 18:24:38 -0700278 /**
279 * @return True if we may show an activity while Keyguard is showing because we are in the
280 * process of dismissing it anyways, false otherwise.
281 */
Jorim Jaggi07961872016-11-23 11:28:57 +0100282 boolean canShowActivityWhileKeyguardShowing(ActivityRecord r, boolean dismissKeyguard) {
283
284 // Allow to show it when we are about to dismiss Keyguard. This isn't allowed if r is
285 // already the dismissing activity, in which case we don't allow it to repeatedly dismiss
286 // Keyguard.
Lucas Dupin47a65c72018-02-15 14:16:18 -0800287 return dismissKeyguard && canDismissKeyguard() && !mAodShowing
wilsonshih0299c8a2018-08-24 15:52:57 +0800288 && (mDismissalRequested
Arthur Hungcf58b332019-04-17 16:07:10 +0800289 || (r.canShowWhenLocked()
290 && getDisplay(r.getDisplayId()).mDismissingKeyguardActivity != r));
Jorim Jaggi07961872016-11-23 11:28:57 +0100291 }
292
293 /**
294 * @return True if we may show an activity while Keyguard is occluded, false otherwise.
295 */
296 boolean canShowWhileOccluded(boolean dismissKeyguard, boolean showWhenLocked) {
Brad Stenning2bdc21e2019-03-11 14:33:22 -0700297 return showWhenLocked || dismissKeyguard
298 && !mWindowManager.isKeyguardSecure(mService.getCurrentUserId());
Jorim Jaggie69c9312016-10-31 18:24:38 -0700299 }
300
Jorim Jaggife762342016-10-13 14:33:27 +0200301 private void visibilitiesUpdated() {
wilsonshih0299c8a2018-08-24 15:52:57 +0800302 boolean requestDismissKeyguard = false;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800303 for (int displayNdx = mRootActivityContainer.getChildCount() - 1;
304 displayNdx >= 0; displayNdx--) {
305 final ActivityDisplay display = mRootActivityContainer.getChildAt(displayNdx);
wilsonshih0299c8a2018-08-24 15:52:57 +0800306 final KeyguardDisplayState state = getDisplay(display.mDisplayId);
307 state.visibilitiesUpdated(this, display);
308 requestDismissKeyguard |= state.mRequestDismissKeyguard;
Jorim Jaggife762342016-10-13 14:33:27 +0200309 }
wilsonshih0299c8a2018-08-24 15:52:57 +0800310
311 // Dismissing Keyguard happens globally using the information from all displays.
312 if (requestDismissKeyguard) {
Jorim Jaggife762342016-10-13 14:33:27 +0200313 handleDismissKeyguard();
314 }
315 }
316
317 /**
318 * Called when occluded state changed.
319 */
Issei Suzuki62356a22019-04-11 16:46:37 +0200320 private void handleOccludedChanged(int displayId) {
321 // TODO(b/113840485): Handle app transition for individual display, and apply occluded
322 // state change to secondary displays.
323 // For now, only default display fully supports occluded change. Other displays only
324 // updates keygaurd sleep token on that display.
325 if (displayId != DEFAULT_DISPLAY) {
326 updateKeyguardSleepToken(displayId);
327 return;
328 }
329
Riddle Hsu8419e4b2019-09-18 23:28:01 +0800330 mWindowManager.mPolicy.onKeyguardOccludedChangedLw(isDisplayOccluded(DEFAULT_DISPLAY));
Jorim Jaggife762342016-10-13 14:33:27 +0200331 if (isKeyguardLocked()) {
Riddle Hsua0022cd2019-09-09 21:12:41 +0800332 mService.deferWindowLayout();
Jorim Jaggife762342016-10-13 14:33:27 +0200333 try {
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800334 mRootActivityContainer.getDefaultDisplay().mDisplayContent
lumark588a3e82018-07-20 18:53:54 +0800335 .prepareAppTransition(resolveOccludeTransit(),
336 false /* alwaysKeepCurrent */, 0 /* flags */,
337 true /* forceOverride */);
Issei Suzuki62356a22019-04-11 16:46:37 +0200338 updateKeyguardSleepToken(DEFAULT_DISPLAY);
Wale Ogunwaled32da472018-11-16 07:19:28 -0800339 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
Jorim Jaggife762342016-10-13 14:33:27 +0200340 mWindowManager.executeAppTransition();
341 } finally {
Riddle Hsua0022cd2019-09-09 21:12:41 +0800342 mService.continueWindowLayout();
Jorim Jaggife762342016-10-13 14:33:27 +0200343 }
344 }
345 dismissDockedStackIfNeeded();
346 }
347
348 /**
wilsonshih0299c8a2018-08-24 15:52:57 +0800349 * Called when somebody wants to dismiss the Keyguard via the flag.
Jorim Jaggife762342016-10-13 14:33:27 +0200350 */
351 private void handleDismissKeyguard() {
Jorim Jaggi07961872016-11-23 11:28:57 +0100352 // We only allow dismissing Keyguard via the flag when Keyguard is secure for legacy
353 // reasons, because that's how apps used to dismiss Keyguard in the secure case. In the
354 // insecure case, we actually show it on top of the lockscreen. See #canShowWhileOccluded.
Brad Stenning2bdc21e2019-03-11 14:33:22 -0700355 if (!mWindowManager.isKeyguardSecure(mService.getCurrentUserId())) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800356 return;
357 }
Jorim Jaggife762342016-10-13 14:33:27 +0200358
Wale Ogunwaled32da472018-11-16 07:19:28 -0800359 mWindowManager.dismissKeyguard(null /* callback */, null /* message */);
360 mDismissalRequested = true;
361
362 // If we are about to unocclude the Keyguard, but we can dismiss it without security,
363 // we immediately dismiss the Keyguard so the activity gets shown without a flicker.
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800364 final DisplayContent dc =
365 mRootActivityContainer.getDefaultDisplay().mDisplayContent;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800366 if (mKeyguardShowing && canDismissKeyguard()
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800367 && dc.mAppTransition.getAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE) {
368 dc.prepareAppTransition(mBeforeUnoccludeTransit, false /* alwaysKeepCurrent */,
Wale Ogunwaled32da472018-11-16 07:19:28 -0800369 0 /* flags */, true /* forceOverride */);
370 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
371 mWindowManager.executeAppTransition();
Jorim Jaggife762342016-10-13 14:33:27 +0200372 }
373 }
374
Issei Suzuki16d4de52019-07-29 13:12:01 +0000375 private boolean isDisplayOccluded(int displayId) {
wilsonshih0299c8a2018-08-24 15:52:57 +0800376 return getDisplay(displayId).mOccluded;
377 }
378
Jorim Jaggife762342016-10-13 14:33:27 +0200379 /**
380 * @return true if Keyguard can be currently dismissed without entering credentials.
381 */
Andrii Kulianfc8f82b2017-01-26 13:17:27 -0800382 boolean canDismissKeyguard() {
Riddle Hsu8419e4b2019-09-18 23:28:01 +0800383 return mWindowManager.mPolicy.isKeyguardTrustedLw()
Brad Stenning2bdc21e2019-03-11 14:33:22 -0700384 || !mWindowManager.isKeyguardSecure(mService.getCurrentUserId());
Jorim Jaggife762342016-10-13 14:33:27 +0200385 }
386
387 private int resolveOccludeTransit() {
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800388 final DisplayContent dc =
389 mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent;
Jorim Jaggife762342016-10-13 14:33:27 +0200390 if (mBeforeUnoccludeTransit != TRANSIT_UNSET
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800391 && dc.mAppTransition.getAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE
wilsonshih0299c8a2018-08-24 15:52:57 +0800392 // TODO(b/113840485): Handle app transition for individual display.
Issei Suzuki16d4de52019-07-29 13:12:01 +0000393 && isDisplayOccluded(DEFAULT_DISPLAY)) {
Jorim Jaggife762342016-10-13 14:33:27 +0200394
395 // Reuse old transit in case we are occluding Keyguard again, meaning that we never
396 // actually occclude/unocclude Keyguard, but just run a normal transition.
397 return mBeforeUnoccludeTransit;
wilsonshih0299c8a2018-08-24 15:52:57 +0800398 // TODO(b/113840485): Handle app transition for individual display.
Issei Suzuki16d4de52019-07-29 13:12:01 +0000399 } else if (!isDisplayOccluded(DEFAULT_DISPLAY)) {
Jorim Jaggife762342016-10-13 14:33:27 +0200400
401 // Save transit in case we dismiss/occlude Keyguard shortly after.
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800402 mBeforeUnoccludeTransit = dc.mAppTransition.getAppTransition();
Jorim Jaggife762342016-10-13 14:33:27 +0200403 return TRANSIT_KEYGUARD_UNOCCLUDE;
404 } else {
405 return TRANSIT_KEYGUARD_OCCLUDE;
406 }
407 }
408
409 private void dismissDockedStackIfNeeded() {
wilsonshih0299c8a2018-08-24 15:52:57 +0800410 // TODO(b/113840485): Handle docked stack for individual display.
Issei Suzuki16d4de52019-07-29 13:12:01 +0000411 if (mKeyguardShowing && isDisplayOccluded(DEFAULT_DISPLAY)) {
Jorim Jaggife762342016-10-13 14:33:27 +0200412 // The lock screen is currently showing, but is occluded by a window that can
413 // show on top of the lock screen. In this can we want to dismiss the docked
414 // stack since it will be complicated/risky to try to put the activity on top
415 // of the lock screen in the right fullscreen configuration.
Wale Ogunwaled32da472018-11-16 07:19:28 -0800416 final ActivityStack stack =
417 mRootActivityContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700418 if (stack == null) {
419 return;
420 }
421 mStackSupervisor.moveTasksToFullscreenStackLocked(stack,
Andrii Kulian52d255c2018-07-13 11:32:19 -0700422 stack.isFocusedStackOnDisplay());
Jorim Jaggife762342016-10-13 14:33:27 +0200423 }
424 }
Jorim Jaggi8d786932016-10-26 19:08:36 -0700425
David Stevens9440dc82017-03-16 19:00:20 -0700426 private void updateKeyguardSleepToken() {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800427 for (int displayNdx = mRootActivityContainer.getChildCount() - 1;
428 displayNdx >= 0; displayNdx--) {
429 final ActivityDisplay display = mRootActivityContainer.getChildAt(displayNdx);
Issei Suzuki62356a22019-04-11 16:46:37 +0200430 updateKeyguardSleepToken(display.mDisplayId);
431 }
432 }
433
434 private void updateKeyguardSleepToken(int displayId) {
435 final KeyguardDisplayState state = getDisplay(displayId);
Issei Suzuki16d4de52019-07-29 13:12:01 +0000436 if (isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken == null) {
Issei Suzuki62356a22019-04-11 16:46:37 +0200437 state.acquiredSleepToken();
Issei Suzuki16d4de52019-07-29 13:12:01 +0000438 } else if (!isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken != null) {
Issei Suzuki62356a22019-04-11 16:46:37 +0200439 state.releaseSleepToken();
wilsonshih0299c8a2018-08-24 15:52:57 +0800440 }
441 }
442
443 private KeyguardDisplayState getDisplay(int displayId) {
wilsonshihe7903ea2018-09-26 16:17:59 +0800444 KeyguardDisplayState state = mDisplayStates.get(displayId);
445 if (state == null) {
446 state = new KeyguardDisplayState(mService, displayId);
447 mDisplayStates.append(displayId, state);
wilsonshih0299c8a2018-08-24 15:52:57 +0800448 }
wilsonshihe7903ea2018-09-26 16:17:59 +0800449 return state;
wilsonshih0299c8a2018-08-24 15:52:57 +0800450 }
451
452 void onDisplayRemoved(int displayId) {
wilsonshihe7903ea2018-09-26 16:17:59 +0800453 final KeyguardDisplayState state = mDisplayStates.get(displayId);
454 if (state != null) {
455 state.onRemoved();
wilsonshih0299c8a2018-08-24 15:52:57 +0800456 mDisplayStates.remove(displayId);
457 }
458 }
459
460 /** Represents Keyguard state per individual display. */
461 private static class KeyguardDisplayState {
462 private final int mDisplayId;
463 private boolean mOccluded;
464 private ActivityRecord mDismissingKeyguardActivity;
465 private boolean mRequestDismissKeyguard;
466 private final ActivityTaskManagerService mService;
467 private SleepToken mSleepToken;
468
469 KeyguardDisplayState(ActivityTaskManagerService service, int displayId) {
470 mService = service;
471 mDisplayId = displayId;
472 }
473
474 void onRemoved() {
475 mDismissingKeyguardActivity = null;
476 releaseSleepToken();
477 }
478
479 void acquiredSleepToken() {
480 if (mSleepToken == null) {
481 mSleepToken = mService.acquireSleepToken("keyguard", mDisplayId);
482 }
483 }
484
485 void releaseSleepToken() {
486 if (mSleepToken != null) {
487 mSleepToken.release();
488 mSleepToken = null;
489 }
490 }
491
492 void visibilitiesUpdated(KeyguardController controller, ActivityDisplay display) {
493 final boolean lastOccluded = mOccluded;
494 final ActivityRecord lastDismissActivity = mDismissingKeyguardActivity;
495 mRequestDismissKeyguard = false;
496 mOccluded = false;
497 mDismissingKeyguardActivity = null;
498
wilsonshih9a10e9d2019-01-11 14:39:27 +0800499 final ActivityStack stack = getStackForControllingOccluding(display);
500 if (stack != null) {
501 final ActivityRecord topDismissing = stack.getTopDismissingKeyguardActivity();
502 mOccluded = stack.topActivityOccludesKeyguard() || (topDismissing != null
503 && stack.topRunningActivityLocked() == topDismissing
504 && controller.canShowWhileOccluded(
wilsonshih0299c8a2018-08-24 15:52:57 +0800505 true /* dismissKeyguard */,
506 false /* showWhenLocked */));
wilsonshih9a10e9d2019-01-11 14:39:27 +0800507 if (stack.getTopDismissingKeyguardActivity() != null) {
508 mDismissingKeyguardActivity = stack.getTopDismissingKeyguardActivity();
wilsonshih0299c8a2018-08-24 15:52:57 +0800509 }
wilsonshih498a4b82018-12-11 16:10:16 +0800510 // FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD only apply for secondary display.
511 if (mDisplayId != DEFAULT_DISPLAY) {
512 mOccluded |= stack.canShowWithInsecureKeyguard()
513 && controller.canDismissKeyguard();
514 }
wilsonshih0299c8a2018-08-24 15:52:57 +0800515 }
wilsonshih498a4b82018-12-11 16:10:16 +0800516 // TODO(b/123372519): isShowingDream can only works on default display.
517 if (mDisplayId == DEFAULT_DISPLAY) {
Riddle Hsu8419e4b2019-09-18 23:28:01 +0800518 mOccluded |= mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent
519 .getDisplayPolicy().isShowingDreamLw();
wilsonshih498a4b82018-12-11 16:10:16 +0800520 }
wilsonshih0299c8a2018-08-24 15:52:57 +0800521
Issei Suzuki62356a22019-04-11 16:46:37 +0200522 if (lastOccluded != mOccluded) {
523 controller.handleOccludedChanged(mDisplayId);
wilsonshih0299c8a2018-08-24 15:52:57 +0800524 }
525 if (lastDismissActivity != mDismissingKeyguardActivity && !mOccluded
526 && mDismissingKeyguardActivity != null
Brad Stenning2bdc21e2019-03-11 14:33:22 -0700527 && controller.mWindowManager.isKeyguardSecure(
528 controller.mService.getCurrentUserId())) {
wilsonshih0299c8a2018-08-24 15:52:57 +0800529 mRequestDismissKeyguard = true;
530 }
531 }
532
wilsonshih9a10e9d2019-01-11 14:39:27 +0800533 /**
534 * Gets the stack used to check the occluded state.
535 * <p>
536 * Only the top non-pinned activity of the focusable stack on each display can control its
537 * occlusion state.
538 */
539 private ActivityStack getStackForControllingOccluding(ActivityDisplay display) {
540 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
541 final ActivityStack stack = display.getChildAt(stackNdx);
542 if (stack != null && stack.isFocusableAndVisible()
543 && !stack.inPinnedWindowingMode()) {
544 return stack;
545 }
546 }
547 return null;
548 }
549
wilsonshih0299c8a2018-08-24 15:52:57 +0800550 void dumpStatus(PrintWriter pw, String prefix) {
551 final StringBuilder sb = new StringBuilder();
552 sb.append(prefix);
553 sb.append(" Occluded=").append(mOccluded)
554 .append(" DismissingKeyguardActivity=")
555 .append(mDismissingKeyguardActivity)
556 .append(" at display=")
557 .append(mDisplayId);
558 pw.println(sb.toString());
559 }
560
561 void writeToProto(ProtoOutputStream proto, long fieldId) {
562 final long token = proto.start(fieldId);
563 proto.write(DISPLAY_ID, mDisplayId);
564 proto.write(KEYGUARD_OCCLUDED, mOccluded);
565 proto.end(token);
David Stevens9440dc82017-03-16 19:00:20 -0700566 }
567 }
568
Jorim Jaggi8d786932016-10-26 19:08:36 -0700569 void dump(PrintWriter pw, String prefix) {
570 pw.println(prefix + "KeyguardController:");
571 pw.println(prefix + " mKeyguardShowing=" + mKeyguardShowing);
Lucas Dupin47a65c72018-02-15 14:16:18 -0800572 pw.println(prefix + " mAodShowing=" + mAodShowing);
Jorim Jaggi8d786932016-10-26 19:08:36 -0700573 pw.println(prefix + " mKeyguardGoingAway=" + mKeyguardGoingAway);
wilsonshih0299c8a2018-08-24 15:52:57 +0800574 dumpDisplayStates(pw, prefix);
Jorim Jaggi07961872016-11-23 11:28:57 +0100575 pw.println(prefix + " mDismissalRequested=" + mDismissalRequested);
Jorim Jaggi8d786932016-10-26 19:08:36 -0700576 pw.println(prefix + " mVisibilityTransactionDepth=" + mVisibilityTransactionDepth);
577 }
Steven Timotius4346f0a2017-09-12 11:07:21 -0700578
579 void writeToProto(ProtoOutputStream proto, long fieldId) {
580 final long token = proto.start(fieldId);
Issei Suzukid6eb5a22019-02-20 23:08:03 +0100581 proto.write(AOD_SHOWING, mAodShowing);
Steven Timotius4346f0a2017-09-12 11:07:21 -0700582 proto.write(KEYGUARD_SHOWING, mKeyguardShowing);
wilsonshih0299c8a2018-08-24 15:52:57 +0800583 writeDisplayStatesToProto(proto, KEYGUARD_OCCLUDED_STATES);
Steven Timotius4346f0a2017-09-12 11:07:21 -0700584 proto.end(token);
585 }
wilsonshih0299c8a2018-08-24 15:52:57 +0800586
587 private void dumpDisplayStates(PrintWriter pw, String prefix) {
588 for (int i = 0; i < mDisplayStates.size(); i++) {
589 mDisplayStates.valueAt(i).dumpStatus(pw, prefix);
590 }
591 }
592
593 private void writeDisplayStatesToProto(ProtoOutputStream proto, long fieldId) {
594 for (int i = 0; i < mDisplayStates.size(); i++) {
595 mDisplayStates.valueAt(i).writeToProto(proto, fieldId);
596 }
597 }
Jorim Jaggife762342016-10-13 14:33:27 +0200598}