The big Keyguard transition refactor (8/n)

Don't force mKeyguardGoingAway, as this never recovers. Make sure
to only show the dismissing Keyguard activtiy and recover the
state when trusted state changes.

Test: Make sure Keyguard is in a trusted state, start an activity
with FLAG_DISMISS_KEYGUARD from FLAG_SHOW_WHEN_LOCKED activity
and make sure there is no flicker.

Bug: 32057734
Change-Id: I5d212f6f9d5430250b22c8370f45dc95756432d2
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index e56fe0f..38e3572 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -194,4 +194,9 @@
      * @return {@code true} if system is ready, {@code false} otherwise.
      */
     public abstract boolean isSystemReady();
+
+    /**
+     * Called when the trusted state of Keyguard has changed.
+     */
+    public abstract void notifyKeyguardTrustedChanged();
 }
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 8a9bb33..4195d91 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -509,6 +509,11 @@
          * Notifies window manager that {@link #isShowingDreamLw} has changed.
          */
         void notifyShowingDreamChanged();
+
+        /**
+         * Notifies window manager that {@link #isKeyguardTrustedLw} has changed.
+         */
+        void notifyKeyguardTrustedChanged();
     }
 
     public interface PointerEventListener {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2d6832d..afb4680 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -22077,6 +22077,15 @@
             // no need to synchronize(this) just to read & return the value
             return mSystemReady;
         }
+
+        @Override
+        public void notifyKeyguardTrustedChanged() {
+            synchronized (ActivityManagerService.this) {
+                if (mKeyguardController.isKeyguardShowing()) {
+                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+                }
+            }
+        }
     }
 
     private final class SleepTokenImpl extends SleepToken {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 0d79980..1bdef43 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1806,8 +1806,9 @@
         final boolean keyguardShowing = mStackSupervisor.mKeyguardController.isKeyguardShowing();
         final boolean keyguardLocked = mStackSupervisor.mKeyguardController.isKeyguardLocked();
         final boolean showWhenLocked = r.hasShowWhenLockedWindows();
+        final boolean dismissKeyguard = r.hasDismissKeyguardWindows();
         if (shouldBeVisible) {
-            if (r.hasDismissKeyguardWindows() && mTopDismissingKeyguardActivity == null) {
+            if (dismissKeyguard && mTopDismissingKeyguardActivity == null) {
                 mTopDismissingKeyguardActivity = r;
             }
 
@@ -1819,8 +1820,10 @@
         }
         if (keyguardShowing) {
 
-            // If keyguard is showing, nothing is visible.
-            return false;
+            // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard
+            // right away.
+            return shouldBeVisible && mStackSupervisor.mKeyguardController
+                    .canShowActivityWhileKeyguardShowing(dismissKeyguard);
         } else if (keyguardLocked) {
 
             // Show when locked windows above keyguard.
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index 98acc9c..9d8c383 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -154,6 +154,14 @@
         }
     }
 
+    /**
+     * @return True if we may show an activity while Keyguard is showing because we are in the
+     *         process of dismissing it anyways, false otherwise.
+     */
+    boolean canShowActivityWhileKeyguardShowing(boolean dismissKeyguard) {
+        return dismissKeyguard && canDismissKeyguard();
+    }
+
     private void visibilitiesUpdated() {
         final boolean lastOccluded = mOccluded;
         final ActivityRecord lastDismissingKeyguardActivity = mDismissingKeyguardActivity;
@@ -215,7 +223,6 @@
                     && mWindowManager.getPendingAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE) {
                 mWindowManager.prepareAppTransition(mBeforeUnoccludeTransit,
                         false /* alwaysKeepCurrent */, 0 /* flags */, true /* forceOverride */);
-                mKeyguardGoingAway = true;
                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                 mWindowManager.executeAppTransition();
             }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index b7067d2..396c958 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -226,6 +226,7 @@
 import com.android.server.LocalServices;
 import com.android.server.policy.keyguard.KeyguardServiceDelegate;
 import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
+import com.android.server.policy.keyguard.KeyguardStateMonitor.StateCallback;
 import com.android.server.statusbar.StatusBarManagerInternal;
 import com.android.server.wm.AppTransition;
 
@@ -6956,7 +6957,13 @@
     /** {@inheritDoc} */
     @Override
     public void systemReady() {
-        mKeyguardDelegate = new KeyguardServiceDelegate(mContext);
+        mKeyguardDelegate = new KeyguardServiceDelegate(mContext,
+                new StateCallback() {
+                    @Override
+                    public void onTrustedChanged() {
+                        mWindowManagerFuncs.notifyKeyguardTrustedChanged();
+                    }
+                });
         mKeyguardDelegate.onSystemReady();
 
         readCameraLensCoverState();
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 28f36f7..ca641fb 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -1,7 +1,5 @@
 package com.android.server.policy.keyguard;
 
-import android.app.ActivityManager;
-import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerNative;
 import android.content.ComponentName;
 import android.content.Context;
@@ -15,13 +13,11 @@
 import android.os.UserHandle;
 import android.util.Log;
 import android.util.Slog;
-import android.view.View;
 import android.view.WindowManagerPolicy.OnKeyguardExitResult;
 
 import com.android.internal.policy.IKeyguardDrawnCallback;
 import com.android.internal.policy.IKeyguardExitCallback;
 import com.android.internal.policy.IKeyguardService;
-import com.android.server.LocalServices;
 import com.android.server.UiThread;
 
 import java.io.PrintWriter;
@@ -47,6 +43,8 @@
     private final Context mContext;
     private final Handler mHandler;
     private final KeyguardState mKeyguardState = new KeyguardState();
+    private final KeyguardStateMonitor.StateCallback mCallback;
+
     private DrawnListener mDrawnListenerWhenConnect;
 
     private static final class KeyguardState {
@@ -119,9 +117,10 @@
         }
     };
 
-    public KeyguardServiceDelegate(Context context) {
+    public KeyguardServiceDelegate(Context context, KeyguardStateMonitor.StateCallback callback) {
         mContext = context;
         mHandler = UiThread.getHandler();
+        mCallback = callback;
     }
 
     public void bindService(Context context) {
@@ -155,7 +154,7 @@
         public void onServiceConnected(ComponentName name, IBinder service) {
             if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)");
             mKeyguardService = new KeyguardServiceWrapper(mContext,
-                    IKeyguardService.Stub.asInterface(service));
+                    IKeyguardService.Stub.asInterface(service), mCallback);
             if (mKeyguardState.systemIsReady) {
                 // If the system is ready, it means keyguard crashed and restarted.
                 mKeyguardService.onSystemReady();
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
index b457f8d..c4a0dd3 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@@ -39,9 +39,10 @@
     private IKeyguardService mService;
     private String TAG = "KeyguardServiceWrapper";
 
-    public KeyguardServiceWrapper(Context context, IKeyguardService service) {
+    public KeyguardServiceWrapper(Context context, IKeyguardService service,
+            KeyguardStateMonitor.StateCallback callback) {
         mService = service;
-        mKeyguardStateMonitor = new KeyguardStateMonitor(context, service);
+        mKeyguardStateMonitor = new KeyguardStateMonitor(context, service, callback);
     }
 
     @Override // Binder interface
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index f19f0aa..941cd44 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -49,10 +49,12 @@
     private int mCurrentUserId;
 
     private final LockPatternUtils mLockPatternUtils;
+    private final StateCallback mCallback;
 
-    public KeyguardStateMonitor(Context context, IKeyguardService service) {
+    public KeyguardStateMonitor(Context context, IKeyguardService service, StateCallback callback) {
         mLockPatternUtils = new LockPatternUtils(context);
         mCurrentUserId = ActivityManager.getCurrentUser();
+        mCallback = callback;
 
         try {
             service.addStateMonitorCallback(this);
@@ -107,6 +109,7 @@
     @Override // Binder interface
     public void onTrustedChanged(boolean trusted) {
         mTrusted = trusted;
+        mCallback.onTrustedChanged();
     }
 
     @Override // Binder interface
@@ -114,6 +117,10 @@
         mHasLockscreenWallpaper = hasLockscreenWallpaper;
     }
 
+    public interface StateCallback {
+        void onTrustedChanged();
+    }
+
     public void dump(String prefix, PrintWriter pw) {
         pw.println(prefix + TAG);
         prefix += "  ";
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7723752..f4acd34 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3572,6 +3572,11 @@
         notifyKeyguardFlagsChanged(null /* callback */);
     }
 
+    @Override
+    public void notifyKeyguardTrustedChanged() {
+        mH.sendEmptyMessage(H.NOTIFY_KEYGUARD_TRUSTED_CHANGED);
+    }
+
     /**
      * Re-sizes a stack and its containing tasks.
      * @param stackId Id of stack to resize.
@@ -6110,6 +6115,7 @@
         public static final int SEAMLESS_ROTATION_TIMEOUT = 54;
         public static final int RESTORE_POINTER_ICON = 55;
         public static final int NOTIFY_KEYGUARD_FLAGS_CHANGED = 56;
+        public static final int NOTIFY_KEYGUARD_TRUSTED_CHANGED = 57;
 
         /**
          * Used to denote that an integer field in a message will not be used.
@@ -6748,6 +6754,11 @@
                 case NOTIFY_KEYGUARD_FLAGS_CHANGED: {
                     mAmInternal.notifyKeyguardFlagsChanged((Runnable) msg.obj);
                 }
+                break;
+                case NOTIFY_KEYGUARD_TRUSTED_CHANGED: {
+                    mAmInternal.notifyKeyguardTrustedChanged();
+                }
+                break;
             }
             if (DEBUG_WINDOW_TRACE) {
                 Slog.v(TAG_WM, "handleMessage: exit");