blob: 3560635ced09853a7c3718c9e27c47985dec3c77 [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;
David Stevens53a39ea2017-08-23 18:41:49 -070021import static android.view.Display.INVALID_DISPLAY;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070022import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
23import 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;
30import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
31import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
wilsonshih0299c8a2018-08-24 15:52:57 +080032
Wale Ogunwale59507092018-10-29 09:00:30 -070033import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
34import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
35import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
wilsonshih0299c8a2018-08-24 15:52:57 +080036import static com.android.server.am.KeyguardControllerProto.KEYGUARD_OCCLUDED_STATES;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070037import static com.android.server.am.KeyguardControllerProto.KEYGUARD_SHOWING;
wilsonshih0299c8a2018-08-24 15:52:57 +080038import static com.android.server.am.KeyguardOccludedProto.DISPLAY_ID;
39import static com.android.server.am.KeyguardOccludedProto.KEYGUARD_OCCLUDED;
Jorim Jaggife762342016-10-13 14:33:27 +020040
Jorim Jaggi241ae102016-11-02 21:57:33 -070041import android.os.IBinder;
42import android.os.RemoteException;
Wale Ogunwaledfb7fb22017-06-23 14:52:40 -070043import android.os.Trace;
Jorim Jaggi241ae102016-11-02 21:57:33 -070044import android.util.Slog;
wilsonshih0299c8a2018-08-24 15:52:57 +080045import android.util.SparseArray;
Steven Timotius4346f0a2017-09-12 11:07:21 -070046import android.util.proto.ProtoOutputStream;
Adrian Roose99bc052017-11-20 17:55:31 +010047
Jorim Jaggi241ae102016-11-02 21:57:33 -070048import com.android.internal.policy.IKeyguardDismissCallback;
Adrian Roose99bc052017-11-20 17:55:31 +010049import com.android.server.policy.WindowManagerPolicy;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070050import com.android.server.wm.ActivityTaskManagerInternal.SleepToken;
Adrian Roose99bc052017-11-20 17:55:31 +010051
Jorim Jaggi8d786932016-10-26 19:08:36 -070052import java.io.PrintWriter;
Jorim Jaggife762342016-10-13 14:33:27 +020053
54/**
55 * Controls Keyguard occluding, dismissing and transitions depending on what kind of activities are
56 * currently visible.
57 * <p>
58 * Note that everything in this class should only be accessed with the AM lock being held.
59 */
60class KeyguardController {
61
Wale Ogunwale98875612018-10-12 07:53:02 -070062 private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardController" : TAG_ATM;
Jorim Jaggi241ae102016-11-02 21:57:33 -070063
Jorim Jaggife762342016-10-13 14:33:27 +020064 private final ActivityStackSupervisor mStackSupervisor;
65 private WindowManagerService mWindowManager;
Jorim Jaggife762342016-10-13 14:33:27 +020066 private boolean mKeyguardShowing;
Lucas Dupin47a65c72018-02-15 14:16:18 -080067 private boolean mAodShowing;
Jorim Jaggi8d786932016-10-26 19:08:36 -070068 private boolean mKeyguardGoingAway;
Jorim Jaggi07961872016-11-23 11:28:57 +010069 private boolean mDismissalRequested;
Jorim Jaggife762342016-10-13 14:33:27 +020070 private int mBeforeUnoccludeTransit;
71 private int mVisibilityTransactionDepth;
wilsonshih0299c8a2018-08-24 15:52:57 +080072 // TODO(b/111955725): Support multiple external displays
David Stevens53a39ea2017-08-23 18:41:49 -070073 private int mSecondaryDisplayShowing = INVALID_DISPLAY;
wilsonshih0299c8a2018-08-24 15:52:57 +080074 private final SparseArray<KeyguardDisplayState> mDisplayStates = new SparseArray<>();
75 private final ActivityTaskManagerService mService;
Jorim Jaggife762342016-10-13 14:33:27 +020076
Wale Ogunwalef6733932018-06-27 05:14:34 -070077 KeyguardController(ActivityTaskManagerService service,
Jorim Jaggife762342016-10-13 14:33:27 +020078 ActivityStackSupervisor stackSupervisor) {
79 mService = service;
80 mStackSupervisor = stackSupervisor;
81 }
82
83 void setWindowManager(WindowManagerService windowManager) {
84 mWindowManager = windowManager;
85 }
86
87 /**
Lucas Dupin47a65c72018-02-15 14:16:18 -080088 * @return true if either Keyguard or AOD are showing, not going away, and not being occluded
89 * on the given display, false otherwise
90 */
91 boolean isKeyguardOrAodShowing(int displayId) {
wilsonshih0299c8a2018-08-24 15:52:57 +080092 return (mKeyguardShowing || mAodShowing) && !mKeyguardGoingAway
93 && !isDisplayOccluded(displayId);
Lucas Dupin47a65c72018-02-15 14:16:18 -080094 }
95
96 /**
David Stevens53a39ea2017-08-23 18:41:49 -070097 * @return true if Keyguard is showing, not going away, and not being occluded on the given
98 * display, false otherwise
Jorim Jaggife762342016-10-13 14:33:27 +020099 */
David Stevens53a39ea2017-08-23 18:41:49 -0700100 boolean isKeyguardShowing(int displayId) {
wilsonshih0299c8a2018-08-24 15:52:57 +0800101 return mKeyguardShowing && !mKeyguardGoingAway && !isDisplayOccluded(displayId);
Jorim Jaggife762342016-10-13 14:33:27 +0200102 }
103
104 /**
105 * @return true if Keyguard is either showing or occluded, but not going away
106 */
107 boolean isKeyguardLocked() {
108 return mKeyguardShowing && !mKeyguardGoingAway;
109 }
110
111 /**
Bryce Lee271617a2018-03-15 10:39:12 -0700112 * @return {@code true} if the keyguard is going away, {@code false} otherwise.
113 */
114 boolean isKeyguardGoingAway() {
115 // Also check keyguard showing in case value is stale.
116 return mKeyguardGoingAway && mKeyguardShowing;
117 }
118
119 /**
Jorim Jaggife762342016-10-13 14:33:27 +0200120 * Update the Keyguard showing state.
121 */
Lucas Dupin47a65c72018-02-15 14:16:18 -0800122 void setKeyguardShown(boolean keyguardShowing, boolean aodShowing,
123 int secondaryDisplayShowing) {
124 boolean showingChanged = keyguardShowing != mKeyguardShowing || aodShowing != mAodShowing;
Adrian Roos6ec76b72018-04-25 14:01:11 +0200125 // If keyguard is going away, but SystemUI aborted the transition, need to reset state.
126 showingChanged |= mKeyguardGoingAway && keyguardShowing;
David Stevens53a39ea2017-08-23 18:41:49 -0700127 if (!showingChanged && secondaryDisplayShowing == mSecondaryDisplayShowing) {
Jorim Jaggife762342016-10-13 14:33:27 +0200128 return;
129 }
Lucas Dupin47a65c72018-02-15 14:16:18 -0800130 mKeyguardShowing = keyguardShowing;
131 mAodShowing = aodShowing;
David Stevens53a39ea2017-08-23 18:41:49 -0700132 mSecondaryDisplayShowing = secondaryDisplayShowing;
chaviw0e9fb132018-06-05 16:29:13 -0700133 mWindowManager.setAodShowing(aodShowing);
David Stevens53a39ea2017-08-23 18:41:49 -0700134 if (showingChanged) {
135 dismissDockedStackIfNeeded();
Andrii Kulian0d595f32018-02-21 15:47:33 -0800136 setKeyguardGoingAway(false);
wilsonshih0299c8a2018-08-24 15:52:57 +0800137 // TODO(b/113840485): Check usage for non-default display
Adrian Roosb56b3c32018-05-17 17:32:26 +0200138 mWindowManager.setKeyguardOrAodShowingOnDefaultDisplay(
139 isKeyguardOrAodShowing(DEFAULT_DISPLAY));
Lucas Dupin47a65c72018-02-15 14:16:18 -0800140 if (keyguardShowing) {
David Stevens53a39ea2017-08-23 18:41:49 -0700141 mDismissalRequested = false;
142 }
Jorim Jaggife762342016-10-13 14:33:27 +0200143 }
144 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
David Stevens9440dc82017-03-16 19:00:20 -0700145 updateKeyguardSleepToken();
Jorim Jaggife762342016-10-13 14:33:27 +0200146 }
147
148 /**
149 * Called when Keyguard is going away.
150 *
Adrian Roose99bc052017-11-20 17:55:31 +0100151 * @param flags See {@link WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
Jorim Jaggife762342016-10-13 14:33:27 +0200152 * etc.
153 */
154 void keyguardGoingAway(int flags) {
Wale Ogunwaledfb7fb22017-06-23 14:52:40 -0700155 if (!mKeyguardShowing) {
156 return;
157 }
158 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway");
159 mWindowManager.deferSurfaceLayout();
160 try {
161 setKeyguardGoingAway(true);
lumark588a3e82018-07-20 18:53:54 +0800162 mStackSupervisor.getDefaultDisplay().getWindowContainerController()
163 .prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
164 false /* alwaysKeepCurrent */, convertTransitFlags(flags),
165 false /* forceOverride */);
David Stevens9440dc82017-03-16 19:00:20 -0700166 updateKeyguardSleepToken();
Jorim Jaggife762342016-10-13 14:33:27 +0200167
Wale Ogunwaledfb7fb22017-06-23 14:52:40 -0700168 // Some stack visibility might change (e.g. docked stack)
Andrii Kulianab132ee2018-07-24 22:10:21 +0800169 mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
Wale Ogunwaledfb7fb22017-06-23 14:52:40 -0700170 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
171 mStackSupervisor.addStartingWindowsForVisibleActivities(true /* taskSwitch */);
172 mWindowManager.executeAppTransition();
173 } finally {
174 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway: surfaceLayout");
175 mWindowManager.continueSurfaceLayout();
176 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
177
178 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
Jorim Jaggife762342016-10-13 14:33:27 +0200179 }
180 }
181
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800182 void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, CharSequence message) {
Jorim Jaggi241ae102016-11-02 21:57:33 -0700183 final ActivityRecord activityRecord = ActivityRecord.forTokenLocked(token);
184 if (activityRecord == null || !activityRecord.visibleIgnoringKeyguard) {
185 failCallback(callback);
186 return;
187 }
Jorim Jaggid7214892017-07-18 14:05:19 +0200188 Slog.i(TAG, "Activity requesting to dismiss Keyguard: " + activityRecord);
chaviw59b98852017-06-13 12:05:44 -0700189
190 // If the client has requested to dismiss the keyguard and the Activity has the flag to
191 // turn the screen on, wakeup the screen if it's the top Activity.
192 if (activityRecord.getTurnScreenOnFlag() && activityRecord.isTopRunningActivity()) {
193 mStackSupervisor.wakeUp("dismissKeyguard");
194 }
195
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800196 mWindowManager.dismissKeyguard(callback, message);
Jorim Jaggi241ae102016-11-02 21:57:33 -0700197 }
198
Wale Ogunwalebfa81ad2017-05-24 15:14:42 -0700199 private void setKeyguardGoingAway(boolean keyguardGoingAway) {
200 mKeyguardGoingAway = keyguardGoingAway;
201 mWindowManager.setKeyguardGoingAway(keyguardGoingAway);
202 }
203
Jorim Jaggi241ae102016-11-02 21:57:33 -0700204 private void failCallback(IKeyguardDismissCallback callback) {
205 try {
206 callback.onDismissError();
207 } catch (RemoteException e) {
208 Slog.w(TAG, "Failed to call callback", e);
209 }
210 }
211
Jorim Jaggife762342016-10-13 14:33:27 +0200212 private int convertTransitFlags(int keyguardGoingAwayFlags) {
213 int result = 0;
214 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0) {
215 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
216 }
217 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0) {
218 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
219 }
220 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0) {
221 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
222 }
223 return result;
224 }
225
226 /**
227 * Starts a batch of visibility updates.
228 */
229 void beginActivityVisibilityUpdate() {
230 mVisibilityTransactionDepth++;
231 }
232
233 /**
234 * Ends a batch of visibility updates. After all batches are done, this method makes sure to
235 * update lockscreen occluded/dismiss state if needed.
236 */
237 void endActivityVisibilityUpdate() {
238 mVisibilityTransactionDepth--;
239 if (mVisibilityTransactionDepth == 0) {
240 visibilitiesUpdated();
241 }
242 }
243
Jorim Jaggie69c9312016-10-31 18:24:38 -0700244 /**
245 * @return True if we may show an activity while Keyguard is showing because we are in the
246 * process of dismissing it anyways, false otherwise.
247 */
Jorim Jaggi07961872016-11-23 11:28:57 +0100248 boolean canShowActivityWhileKeyguardShowing(ActivityRecord r, boolean dismissKeyguard) {
249
250 // Allow to show it when we are about to dismiss Keyguard. This isn't allowed if r is
251 // already the dismissing activity, in which case we don't allow it to repeatedly dismiss
252 // Keyguard.
Lucas Dupin47a65c72018-02-15 14:16:18 -0800253 return dismissKeyguard && canDismissKeyguard() && !mAodShowing
wilsonshih0299c8a2018-08-24 15:52:57 +0800254 && (mDismissalRequested
255 || getDisplay(r.getDisplayId()).mDismissingKeyguardActivity != r);
Jorim Jaggi07961872016-11-23 11:28:57 +0100256 }
257
258 /**
259 * @return True if we may show an activity while Keyguard is occluded, false otherwise.
260 */
261 boolean canShowWhileOccluded(boolean dismissKeyguard, boolean showWhenLocked) {
262 return showWhenLocked || dismissKeyguard && !mWindowManager.isKeyguardSecure();
Jorim Jaggie69c9312016-10-31 18:24:38 -0700263 }
264
Jorim Jaggife762342016-10-13 14:33:27 +0200265 private void visibilitiesUpdated() {
wilsonshih0299c8a2018-08-24 15:52:57 +0800266 boolean requestDismissKeyguard = false;
Pat Plunkett40426e02017-10-31 14:06:29 -0700267 for (int displayNdx = mStackSupervisor.getChildCount() - 1; displayNdx >= 0; displayNdx--) {
268 final ActivityDisplay display = mStackSupervisor.getChildAt(displayNdx);
wilsonshih0299c8a2018-08-24 15:52:57 +0800269 final KeyguardDisplayState state = getDisplay(display.mDisplayId);
270 state.visibilitiesUpdated(this, display);
271 requestDismissKeyguard |= state.mRequestDismissKeyguard;
Jorim Jaggife762342016-10-13 14:33:27 +0200272 }
wilsonshih0299c8a2018-08-24 15:52:57 +0800273
274 // Dismissing Keyguard happens globally using the information from all displays.
275 if (requestDismissKeyguard) {
Jorim Jaggife762342016-10-13 14:33:27 +0200276 handleDismissKeyguard();
277 }
278 }
279
280 /**
281 * Called when occluded state changed.
282 */
283 private void handleOccludedChanged() {
wilsonshih0299c8a2018-08-24 15:52:57 +0800284 mWindowManager.onKeyguardOccludedChanged(isDisplayOccluded(DEFAULT_DISPLAY));
Jorim Jaggife762342016-10-13 14:33:27 +0200285 if (isKeyguardLocked()) {
286 mWindowManager.deferSurfaceLayout();
287 try {
lumark588a3e82018-07-20 18:53:54 +0800288 mStackSupervisor.getDefaultDisplay().getWindowContainerController()
289 .prepareAppTransition(resolveOccludeTransit(),
290 false /* alwaysKeepCurrent */, 0 /* flags */,
291 true /* forceOverride */);
David Stevens9440dc82017-03-16 19:00:20 -0700292 updateKeyguardSleepToken();
Jorim Jaggife762342016-10-13 14:33:27 +0200293 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
294 mWindowManager.executeAppTransition();
295 } finally {
296 mWindowManager.continueSurfaceLayout();
297 }
298 }
299 dismissDockedStackIfNeeded();
300 }
301
302 /**
wilsonshih0299c8a2018-08-24 15:52:57 +0800303 * Called when somebody wants to dismiss the Keyguard via the flag.
Jorim Jaggife762342016-10-13 14:33:27 +0200304 */
305 private void handleDismissKeyguard() {
Jorim Jaggi07961872016-11-23 11:28:57 +0100306 // We only allow dismissing Keyguard via the flag when Keyguard is secure for legacy
307 // reasons, because that's how apps used to dismiss Keyguard in the secure case. In the
308 // insecure case, we actually show it on top of the lockscreen. See #canShowWhileOccluded.
wilsonshih0299c8a2018-08-24 15:52:57 +0800309 if (mWindowManager.isKeyguardSecure()) {
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800310 mWindowManager.dismissKeyguard(null /* callback */, null /* message */);
Jorim Jaggi07961872016-11-23 11:28:57 +0100311 mDismissalRequested = true;
Jorim Jaggife762342016-10-13 14:33:27 +0200312
313 // If we are about to unocclude the Keyguard, but we can dismiss it without security,
314 // we immediately dismiss the Keyguard so the activity gets shown without a flicker.
lumark588a3e82018-07-20 18:53:54 +0800315 final DisplayWindowController dwc =
316 mStackSupervisor.getDefaultDisplay().getWindowContainerController();
Jorim Jaggife762342016-10-13 14:33:27 +0200317 if (mKeyguardShowing && canDismissKeyguard()
lumark588a3e82018-07-20 18:53:54 +0800318 && dwc.getPendingAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE) {
319 dwc.prepareAppTransition(mBeforeUnoccludeTransit, false /* alwaysKeepCurrent */,
320 0 /* flags */, true /* forceOverride */);
Jorim Jaggife762342016-10-13 14:33:27 +0200321 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
322 mWindowManager.executeAppTransition();
323 }
324 }
325 }
326
wilsonshih0299c8a2018-08-24 15:52:57 +0800327 private boolean isDisplayOccluded(int displayId) {
328 return getDisplay(displayId).mOccluded;
329 }
330
Jorim Jaggife762342016-10-13 14:33:27 +0200331 /**
332 * @return true if Keyguard can be currently dismissed without entering credentials.
333 */
Andrii Kulianfc8f82b2017-01-26 13:17:27 -0800334 boolean canDismissKeyguard() {
Jorim Jaggife762342016-10-13 14:33:27 +0200335 return mWindowManager.isKeyguardTrusted() || !mWindowManager.isKeyguardSecure();
336 }
337
338 private int resolveOccludeTransit() {
lumark588a3e82018-07-20 18:53:54 +0800339 final DisplayWindowController dwc =
340 mStackSupervisor.getDefaultDisplay().getWindowContainerController();
Jorim Jaggife762342016-10-13 14:33:27 +0200341 if (mBeforeUnoccludeTransit != TRANSIT_UNSET
lumark588a3e82018-07-20 18:53:54 +0800342 && dwc.getPendingAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE
wilsonshih0299c8a2018-08-24 15:52:57 +0800343 // TODO(b/113840485): Handle app transition for individual display.
344 && isDisplayOccluded(DEFAULT_DISPLAY)) {
Jorim Jaggife762342016-10-13 14:33:27 +0200345
346 // Reuse old transit in case we are occluding Keyguard again, meaning that we never
347 // actually occclude/unocclude Keyguard, but just run a normal transition.
348 return mBeforeUnoccludeTransit;
wilsonshih0299c8a2018-08-24 15:52:57 +0800349 // TODO(b/113840485): Handle app transition for individual display.
350 } else if (!isDisplayOccluded(DEFAULT_DISPLAY)) {
Jorim Jaggife762342016-10-13 14:33:27 +0200351
352 // Save transit in case we dismiss/occlude Keyguard shortly after.
lumark588a3e82018-07-20 18:53:54 +0800353 mBeforeUnoccludeTransit = dwc.getPendingAppTransition();
Jorim Jaggife762342016-10-13 14:33:27 +0200354 return TRANSIT_KEYGUARD_UNOCCLUDE;
355 } else {
356 return TRANSIT_KEYGUARD_OCCLUDE;
357 }
358 }
359
360 private void dismissDockedStackIfNeeded() {
wilsonshih0299c8a2018-08-24 15:52:57 +0800361 // TODO(b/113840485): Handle docked stack for individual display.
362 if (mKeyguardShowing && isDisplayOccluded(DEFAULT_DISPLAY)) {
Jorim Jaggife762342016-10-13 14:33:27 +0200363 // The lock screen is currently showing, but is occluded by a window that can
364 // show on top of the lock screen. In this can we want to dismiss the docked
365 // stack since it will be complicated/risky to try to put the activity on top
366 // of the lock screen in the right fullscreen configuration.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700367 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale9dcf9462017-09-19 15:13:01 -0700368 if (stack == null) {
369 return;
370 }
371 mStackSupervisor.moveTasksToFullscreenStackLocked(stack,
Andrii Kulian52d255c2018-07-13 11:32:19 -0700372 stack.isFocusedStackOnDisplay());
Jorim Jaggife762342016-10-13 14:33:27 +0200373 }
374 }
Jorim Jaggi8d786932016-10-26 19:08:36 -0700375
David Stevens9440dc82017-03-16 19:00:20 -0700376 private void updateKeyguardSleepToken() {
wilsonshih0299c8a2018-08-24 15:52:57 +0800377 for (int displayNdx = mStackSupervisor.getChildCount() - 1; displayNdx >= 0; displayNdx--) {
378 final ActivityDisplay display = mStackSupervisor.getChildAt(displayNdx);
379 final KeyguardDisplayState state = getDisplay(display.mDisplayId);
380 if (isKeyguardOrAodShowing(display.mDisplayId) && state.mSleepToken == null) {
381 state.acquiredSleepToken();
382 } else if (!isKeyguardOrAodShowing(display.mDisplayId) && state.mSleepToken != null) {
383 state.releaseSleepToken();
384 }
385 }
386 }
387
388 private KeyguardDisplayState getDisplay(int displayId) {
389 if (mDisplayStates.get(displayId) == null) {
390 mDisplayStates.append(displayId,
391 new KeyguardDisplayState(mService, displayId));
392 }
393 return mDisplayStates.get(displayId);
394 }
395
396 void onDisplayRemoved(int displayId) {
397 if (mDisplayStates.get(displayId) != null) {
398 mDisplayStates.get(displayId).onRemoved();
399 mDisplayStates.remove(displayId);
400 }
401 }
402
403 /** Represents Keyguard state per individual display. */
404 private static class KeyguardDisplayState {
405 private final int mDisplayId;
406 private boolean mOccluded;
407 private ActivityRecord mDismissingKeyguardActivity;
408 private boolean mRequestDismissKeyguard;
409 private final ActivityTaskManagerService mService;
410 private SleepToken mSleepToken;
411
412 KeyguardDisplayState(ActivityTaskManagerService service, int displayId) {
413 mService = service;
414 mDisplayId = displayId;
415 }
416
417 void onRemoved() {
418 mDismissingKeyguardActivity = null;
419 releaseSleepToken();
420 }
421
422 void acquiredSleepToken() {
423 if (mSleepToken == null) {
424 mSleepToken = mService.acquireSleepToken("keyguard", mDisplayId);
425 }
426 }
427
428 void releaseSleepToken() {
429 if (mSleepToken != null) {
430 mSleepToken.release();
431 mSleepToken = null;
432 }
433 }
434
435 void visibilitiesUpdated(KeyguardController controller, ActivityDisplay display) {
436 final boolean lastOccluded = mOccluded;
437 final ActivityRecord lastDismissActivity = mDismissingKeyguardActivity;
438 mRequestDismissKeyguard = false;
439 mOccluded = false;
440 mDismissingKeyguardActivity = null;
441
442 // Only the top activity of the focused stack on each display may control it's
443 // occluded state.
444 final ActivityStack focusedStack = display.getFocusedStack();
445 if (focusedStack != null) {
446 final ActivityRecord topDismissing =
447 focusedStack.getTopDismissingKeyguardActivity();
448 mOccluded = focusedStack.topActivityOccludesKeyguard() || (topDismissing != null
449 && focusedStack.topRunningActivityLocked() == topDismissing
450 && controller.canShowWhileOccluded(
451 true /* dismissKeyguard */,
452 false /* showWhenLocked */));
453 if (focusedStack.getTopDismissingKeyguardActivity() != null) {
454 mDismissingKeyguardActivity = focusedStack.getTopDismissingKeyguardActivity();
455 }
456 mOccluded |= controller.mWindowManager.isShowingDream();
457 }
458
459 // TODO(b/113840485): Handle app transition for individual display.
460 // For now, only default display can change occluded.
461 if (lastOccluded != mOccluded && mDisplayId == DEFAULT_DISPLAY) {
462 controller.handleOccludedChanged();
463 }
464 if (lastDismissActivity != mDismissingKeyguardActivity && !mOccluded
465 && mDismissingKeyguardActivity != null
466 && controller.mWindowManager.isKeyguardSecure()) {
467 mRequestDismissKeyguard = true;
468 }
469 }
470
471 void dumpStatus(PrintWriter pw, String prefix) {
472 final StringBuilder sb = new StringBuilder();
473 sb.append(prefix);
474 sb.append(" Occluded=").append(mOccluded)
475 .append(" DismissingKeyguardActivity=")
476 .append(mDismissingKeyguardActivity)
477 .append(" at display=")
478 .append(mDisplayId);
479 pw.println(sb.toString());
480 }
481
482 void writeToProto(ProtoOutputStream proto, long fieldId) {
483 final long token = proto.start(fieldId);
484 proto.write(DISPLAY_ID, mDisplayId);
485 proto.write(KEYGUARD_OCCLUDED, mOccluded);
486 proto.end(token);
David Stevens9440dc82017-03-16 19:00:20 -0700487 }
488 }
489
Jorim Jaggi8d786932016-10-26 19:08:36 -0700490 void dump(PrintWriter pw, String prefix) {
491 pw.println(prefix + "KeyguardController:");
492 pw.println(prefix + " mKeyguardShowing=" + mKeyguardShowing);
Lucas Dupin47a65c72018-02-15 14:16:18 -0800493 pw.println(prefix + " mAodShowing=" + mAodShowing);
Jorim Jaggi8d786932016-10-26 19:08:36 -0700494 pw.println(prefix + " mKeyguardGoingAway=" + mKeyguardGoingAway);
wilsonshih0299c8a2018-08-24 15:52:57 +0800495 dumpDisplayStates(pw, prefix);
Jorim Jaggi07961872016-11-23 11:28:57 +0100496 pw.println(prefix + " mDismissalRequested=" + mDismissalRequested);
Jorim Jaggi8d786932016-10-26 19:08:36 -0700497 pw.println(prefix + " mVisibilityTransactionDepth=" + mVisibilityTransactionDepth);
498 }
Steven Timotius4346f0a2017-09-12 11:07:21 -0700499
500 void writeToProto(ProtoOutputStream proto, long fieldId) {
501 final long token = proto.start(fieldId);
502 proto.write(KEYGUARD_SHOWING, mKeyguardShowing);
wilsonshih0299c8a2018-08-24 15:52:57 +0800503 writeDisplayStatesToProto(proto, KEYGUARD_OCCLUDED_STATES);
Steven Timotius4346f0a2017-09-12 11:07:21 -0700504 proto.end(token);
505 }
wilsonshih0299c8a2018-08-24 15:52:57 +0800506
507 private void dumpDisplayStates(PrintWriter pw, String prefix) {
508 for (int i = 0; i < mDisplayStates.size(); i++) {
509 mDisplayStates.valueAt(i).dumpStatus(pw, prefix);
510 }
511 }
512
513 private void writeDisplayStatesToProto(ProtoOutputStream proto, long fieldId) {
514 for (int i = 0; i < mDisplayStates.size(); i++) {
515 mDisplayStates.valueAt(i).writeToProto(proto, fieldId);
516 }
517 }
Jorim Jaggife762342016-10-13 14:33:27 +0200518}